In Python, the top is functional and the bottom is not.
The non-functional type has a time-out and the functional type has passed. What is the difference?
The environment is a python3 environment.
import sys
n, m = map(int, sys.stdin.readline().split())
arr = list(map(int, sys.stdin.readline().split()))
start = 0
end = max(arr)
def solution(arr, start, end):
result = 0
while start <= end:
total = 0
mid = (start + end) // 2
for i in arr:
if i > mid:
total += i - mid
if total < m:
end = mid - 1
else:
result = mid
start = mid + 1
return result
print(solution(arr, start, end))
import sys
n, m = map(int, sys.stdin.readline().split())
arr = list(map(int, sys.stdin.readline().split()))
start = 0
end = max(arr)
result = 0
while start <= end:
total = 0
mid = (start + end) // 2
for i in arr:
if i > mid:
total += i - mid
if total < m:
end = mid - 1
else:
result = mid
start = mid + 1
print(result)
I followed the link to the corresponding SPOJ problem. Looks like for this particular question the limits for python 3 is pretty closely cut and your TLE is due to the I/O. (read the comments here). Your algorithm looks correct.
As far as the discrepancy in functional call and loop is considered. I submitted both your codes to the SPOJ, both were TLE.
I will recommend screening the comments beneath the question for potential pitfalls for the future reference, it is really helpful.
Related
I am new to coding and so the following code I wrote may be incorrect or sub-optimal. However, the problem I have is that I do not understand the input and thus cannot get the code to run (I only tested it with custom inputs).
The essence of the problem is that you have some sequence of numbers and you want to arrange the sequence monotonically (nondecreasing or nonincreasing). You do this by a random shuffle. How many shuffles does it take for you to get to the monotonic sequence via a random shuffle? You can find the problem here and here is my code below:
#!/bin/python3 ------ The following import is given in the prompt
import os
import sys
# Complete the solve function below. Here is my code below
def solve(P):
P.sort()
correct = P
count = []
i = 0
# Here I am trying to calculate the number of ways to get the desired monotonic sequence
# I count the number of repeated numbers in the sequence as separate items in a list
for j in range(i,len(correct)):
if correct[i] != correct[j] or i == len(correct) - 1:
count.append(j-i)
i = j
j = len(correct)
else:
j = j + 1
summ = 0
for k in range(len(count)):
summ = summ + count[k]
if summ == len(correct):
i = len(correct)
poss = [1]*len(count)
for k in range(len(count)):
for l in range(1,count[k]+1):
poss[k] = poss[k]*l
possible = 1
for x in poss:
possible = possible * x
# This is calculating the number of different permutations of n distinct elements
total = 1
n = len(correct)
for i in range(1,n+1):
total = total * i
# Calculating the probability to the 6th decimal place
probability = float(possible / total)
expected = round(1/probability, 6)
print(expected)
# The following code is given in the prompt to input the test cases
if __name__ == '__main__':
fptr = open(os.environ['OUTPUT_PATH'], 'w')
P_count = int(input())
P = list(map(int, input().rstrip().split()))
result = solve(P)
fptr.write(str(result) + '\n')
fptr.close()
In my code, I just assumed that P is the sequence of numbers you receive from the input.
My merge sort implementation is buggy since i am not getting two sorted list before calling merge.I am not sure what is wrong with it.
def mergeSort(arr):
if len(arr) == 1 : return arr
mid = len(arr) // 2
left_half = arr[:mid]
right_half = arr[mid:]
mergeSort(left_half)
mergeSort(right_half)
return merge(left_half,right_half)
def merge(list1,list2):
res = []
i = 0
j = 0
while i < len(list1) and j < len(list2):
if list1[i] < list2[j]:
res.append(list1[i])
i += 1
elif list1[i] > list2[j]:
res.append(list2[j])
j += 1
#Add remaining to res if any
while i < len(list1):
res.append(list1[i])
i += 1
while j < len(list2):
res.append(list2[j])
j += 1
return res
A = [5,1,2,15]
print(mergeSort(A))
My understanding of merge sort is that the space complexity is O(n) since n items in memory (in the final merge).Is quick sort preferred over merge sort just because quick sort is in-place?
I not python expert, but you should write
left_half = arr[:mid]
right_half = arr[mid:]
left_half = mergeSort(left_half)
right_half = mergeSort(right_half)
Because your mergeSort return copy of sorted array.
You have 3 mistakes in your code.
The first is that you don't handle the empty list. You need a <= instead of an == in your second line.
The second is that by simply calling mergeSort(left_half) you suppose that it will sort left_half “by reference”, which it doesn't (same with right_half).
The third is that you aren't doing anything in the case list1[i] == list2[j]. Actually you don't need that elif, you simply need an else. It doesn't matter whether you append list1[i] or list2[j] if they are equal, but you must append one of the two.
Your code should rather be:
def mergeSort(arr):
if len(arr) <= 1 : return arr
mid = len(arr) // 2
left_half = mergeSort(arr[:mid])
right_half = mergeSort(arr[mid:])
return merge(left_half, right_half)
def merge(list1, list2):
res = []
i = 0
j = 0
while i < len(list1) and j < len(list2):
if list1[i] < list2[j]:
res.append(list1[i])
i += 1
else:
res.append(list2[j])
j += 1
#Add remaining to res if any
...
As for your questions about space complexity and comparison with quicksort, there are already answers here on StackOverflow (here and here).
I try to find out the index of a certain Fibonacci number. However my program returned to me this result "Your program took too long to execute. Check your code for infinite loops, or extra input requests" after typing in 1134903171.
num = 1
num_prev = 1
n = int(input())
i = 1
if n < 2:
print(1, 2)
else:
while i <= n + 2:
num_prev, num = num, num + num_prev
i += 1
if n == num:
print(i + 1)
break
elif i == n + 3:
print(-1)
#break`
Thank you guys. The problem of last code is that: if the number isn't a Fibonacci number and meanwhile it is too large, it will took to many loops for the calculation. As I used a web compiler to calculate, they do not allow such "infinity" loop to operate. Then I used a math methode to limite the loop.
import math
N=int(input())
root1=math.sqrt(5*N*N+4)
root2=math.sqrt(5*N*N-4)
i=1
num, num_prev = 1, 1
if root1%1==0 or root2%1==0:
while i <= N+2:
num_prev,num = num,(num+num_prev)
i+=1
if N==num:
print(i+1)
break
else:
print(-1)
But the best answer could be:
prev, next = 1, 1
index = 2
possible_fib = int(input())
while possible_fib > next:
prev, next = next, prev + next
index += 1
if possible_fib == next:
print(index)
else:
print(-1)
I have solved euler problem 12, but it needs some optimization. I have read on the euler forums, but it has not helped me optimized it. However, I have managed to get the solution, I just need to speed it up. It currently takes 4 minutes to run. Here is my code:
import time
def nthtriangle(n):
return (n * (n + 1)) / 2
def numberofnfactors(n):
count = 0
if n==1:
return 1
for i in range(1, 1 + int(n ** 0.5)):
if n % i == 0:
count += 2
return count
def FirstTriangleNumberWithoverxdivisors(divisors):
found = False
counter = 1
while not found:
print(int(nthtriangle(counter)), " ", numberofnfactors(nthtriangle(counter)))
if numberofnfactors(nthtriangle(counter)) > divisors:
print(" first triangle with over ",divisors, " divisors is ", int(nthtriangle(counter)))
found = True
break
counter += 1
start_time = time.time()
FirstTriangleNumberWithoverxdivisors(500)
print("My program took", time.time() - start_time, "to run")
Instead of calculating each triangle number individually, use a generator to get the triangle numbers
from timeit import timeit
def triangle_numbers():
count = 1
num = 0
while True:
num += count
count += 1
yield num
def count_divisors(n):
count = 0
if n==1:
return 1
for i in range(1, 1 + int(n ** 0.5)):
if n % i == 0:
count += 2
return count
print(timeit('next(num for num in triangle_numbers() if count_divisors(num) >= 500)',
globals=globals(), number=1))
Gives me 3.8404819999996107 (seconds) on my machine. You could probably also improve the divisor counting.
What's really slowing you down is calling nthtriangle and numberoffactors more than once in your loop! Plus, those calls to print aren't free.
I am a beginner trying to learn python through MIT OpenCourseware. This problem is from part B of problem set 1. I understand the mathematical expression but I do not know how to write it out in code.
This is the problem:
Determine how long it will take to save enough
money to make the down payment for a house given the following assumptions:
portion_down payment = 0.25 (25%)
You start with a current savings of $0
Assume that you invest your current savings wisely, with an annual return of r = 0.04 (4%)
Your salary increases by a certain percentage every 6 months (semi-annual rise)
Here is a test case:
Enter your starting annual salary: 120000
Enter the percent of your salary to save, as a decimal: .05
Enter the cost of your dream home: 500000
Enter the semiannual raise, as a decimal: .03
Number of months: 142
Here is my code:
annual_salary = float(input('Annual Salary: '))
portion_saved = float(input('Portion saved (decimal): '))
total_cost = float(input('Total Cost of House: '))
semi_annual_rise = float(input('Semi-annual salary rise (decimal): '))
downp = float(0.25*total_cost)
current_savings = 0
monthly_savings = float(portion_saved*annual_salary/12)
ret = 1 + .04/12
rise = 1 + semi_annual_rise
n = 0
while current_savings < downp:
for n in range(0,300,6):
monthly_savings = monthly_savings*(rise)
current_savings = (current_savings + monthly_savings)*(ret)
n += 1
print ('Number of months: ' + str(n))
Under the while loop, I am trying to increase the salary after 6, 12, 18 etc... months. But I dont know how to insert such a conditionI know it's wrong but I do not know how to correct it. Please help me!!
Just make the raise when n%6 == 0 ...
...
n = 0
while current_savings < downp:
n += 1
if n % 6 == 0: #every six months
monthly_savings = monthly_savings*(rise)
current_savings = (current_savings + monthly_savings)*(ret)
...