CODEFORCES 1744B, how could I fix runtime error? - python-3.x

I'm trying to solve the next problem: https://codeforces.com/contest/1744/problem/B
When I run the code in my terminal, it works with the example given in the exercise; but it doesn't when I submit it in CodeForces, it cause a runtime error which I cannot figure out.
def increment(arr, length, option, add):
for i in range(length):
if(option == '0') and (arr[i]%2 == 0):
arr[i] += add
elif(option == '1') and (arr[i]%2 != 0):
arr[i] += add
else:
pass
return arr
def main():
quantityOperation = int(input())
while quantityOperation > 0:
length, times = input().split()
length = int(length)
times = int(times)
arr = [int(x) for x in input().split()]
while times > 0:
opt, add = input().split()
add = int(add)
res = sum(increment(arr, length, opt, add))
print(res)
times -= 1
quantityOperation -= 1
main()

The loop inside your main function doesn't end. You should put quantityOperation -= 1 inside the while loop.
However, your code will still become time limit exceeded after fixing this. The correct idea is to precalculate odd and even sum and modify them according to the queries instead of looping all elements inside increment function every time. You can check the editorial for this problem.

Related

Recursive merge sort - RecursionError: maximum recursion depth exceeded while calling a Python object

I'm very new in programming and Python, so please excuse in advance my lack of knowledge.
I’m trying to implement a recursive merge sort method in a class. However, when I try to run the program I get the following error:
RecursionError: maximum recursion depth exceeded while calling a Python object
This is because of left = self.merge(lst[:middle]) and right = self.merge(lst[middle:]).
Does someone know how this problem could be solved?
def merge(self, lst, reverse=False):
middle = len(lst) // 2
left = self.merge(lst[:middle])
right = self.merge(lst[middle:])
result = []
i, j = 0, 0
if not len(left) or not len(right):
return left or right
while i < len(left) and j < len(right):
if reverse:
if left[i] > right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
else:
if left[i] < right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
if i == len(left) or j == len(right):
result.extend(left[i:] or right[j:])
break
return result
def _merge_sort(self, reverse=False):
lst = list(self.unsorted_tuple)
if len(lst) < 2:
return lst
return self.merge(lst)
The problem is that you don't have a properly defined base case. In case of merge sort this would be checking if the passed list is either empty or has only one element (it is trivially true that it is sorted).
I'm guessing you're trying to do this with if not len(left) or not len(right). There's two problems with that. First, I don't think this code does what you think it does, play with it a bit in isolation to see how it behaves. See how I changed it and try to improve it.
Second, the test for the base case must be checked before calling the function again recursively. You never even come to this part because first thing that your merge function does is to call itself again! Here's a standalone merge function (not defined as a class method, I leave this to you):
def merge(lst, reverse=False):
if len(lst) <= 1:
return lst
middle = len(lst) // 2
left = merge(lst[:middle])
right = merge(lst[middle:])
result = []
i, j = 0, 0
while i < len(left) and j < len(right):
if reverse:
if left[i] > right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
else:
if left[i] < right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
if i == len(left):
result.extend(right[j:])
if j == len(right):
result.extend(left[i:])
return result
I strongly recommend you Aditya Bhargava's Grokking Algorithms - it uses Python and is a good introductory book.

Count not incrementing properly in python while loop

Can anyone tell me why when I input 1, 2, 3, and 4 into this code, my output is 6, 2, 3.00? I thought that every time my while loop evaluated to true it would increment the count by one, but the output is not making sense. It's taking the total of 3 of the numbers, but only 2 for the count? I'm probably just overlooking something so an extra pair of eyes would be awesome.
def calcAverage(total, count):
average = float(total)/float(count)
return format(average, ',.2f')
def inputPositiveInteger():
str_in = input("Please enter a positive integer, anything else to quit: ")
if not str_in.isdigit():
return -1
else:
try:
pos_int = int(str_in)
return pos_int
except:
return -1
def main():
total = 0
count = 0
while inputPositiveInteger() != -1:
total += inputPositiveInteger()
count += 1
else:
if count != 0:
print(total)
print(count)
print(calcAverage(total, count))
main()
The error with your code is that on this piece of code...
while inputPositiveInteger() != -1:
total += inputPositiveInteger()
You first call inputPositiveInteger and throw out the result in your condition. You need to store the result, otherwise one input out of two is ignored and the other is added even if it is -1.
num = inputPositiveInteger()
while num != -1:
total += num
count += 1
num = inputPositiveInteger()
Improvements
Although, note that your code can be significantly improved. See the comments in the following improved version of your code.
def calcAverage(total, count):
# In Python3, / is a float division you do not need a float cast
average = total / count
return format(average, ',.2f')
def inputPositiveInteger():
str_int = input("Please enter a positive integer, anything else to quit: ")
# If str_int.isdigit() returns True you can safely assume the int cast will work
return int(str_int) if str_int.isdigit() else -1
# In Python, we usually rely on this format to run the main script
if __name__ == '__main__':
# Using the second form of iter is a neat way to loop over user inputs
nums = iter(inputPositiveInteger, -1)
sum_ = sum(nums)
print(sum_)
print(len(nums))
print(calcAverage(sum_, len(nums)))
One detail worth reading about in the above code is the second form of iter.

What is wrong with my function? Giving me a blank output

def get_nearest_multiple(minnum, factor):
"""
function get_nearest_multiple will calculate the nearest multiple that is greater than the min. value,
Parameters are the minimum value and factor,
Will return the ans - the nearest multiple
"""
ans = 0
x = 1
while ans < minnum:
if minnum == 0:
ans = 0
else:
ans = x * factor
x += 1
return ans
get_nearest_multiple(0, 1)
if __name__ == '__main__':
get_nearest_multiple(0, 1)
Can't seem to figure out why my function doesn't print out anything. The output doesn't even show up as an error. Just blank.
Nowhere in your code do you have a print() statement which is required to produce an output in the console

Update list in for loop using list.append

The variable mult is not updated as the program runs. What is the issue with this code? The run results show me that the loop is actually working as I wanted but for the list update and final print
number = 18
for i in range(int(number/2)):
i += 1
mults = []
if number % i == 0:
mults = mults.append(i)
print(i)
elif number % i != 0:
pass
elif i == int(number/2):
print(mults)
with this other code I get the error: AttributeError: 'NoneType' object has no attribute 'append'
number = 18
mults = []
for i in range(int(number/2)):
i += 1
if number % i == 0:
mults = mults.append(i)
print(i)
elif number % i != 0:
pass
print(mults)
number = 18
mults = []
for i in range(int(number/2)):
i += 1
if number % i == 0:
mults.append(i)
print(i)
elif number % i != 0:
pass
print(mults)
Few notes, move mults outside of the for loop so you aren't over writing it every time the loop runs.
You don't need that last elif statement, just print(mults) when the for loop is done, is basically the last elif statement.
mults.append(i) is in line meaning it changes the list mults automatically and you don't need to reassign it.

How to fix "maximum recursion depth exceeded" error in python code?

While I was running the code, I got a "maximum recursion depth exceeded in comparison" error. I'm not exactly sure which part of the code to look at to fix this problem. This numToBinary function is basically supposed to convert a number n to a binary number with bit size k. I would greatly appreciate any input on how I can resolve this issue!
def numToBinary(k, n):
''' converts number to binary number bit size k'''
def binary(n):
if n == 0:
return ''
elif n%2 == 1:
return binary(n/2)+'1'
else:
return binary(n/2)+ '0'
temp = binary(n)
if len(temp) <= k:
answer = '0' * (k - len(temp)) + temp
elif len(temp) > k:
answer = temp[-k:]
return answer
print (numToBinary(6, 10))
You need floor division, double /, in python3 / does truediv so you are getting floats from n/2:
def binary(n):
if n == 0:
return ''
elif n%2 == 1:
return binary(n//2) + '1' # // floor
else:
return binary(n//2)+ '0' # // floor
Once you make the change, it will work fine:
In [50]: numToBinary(6, 10)
Out[50]: '001010'
You can also use else in place of the elif, if the len of temp is not <= then it has to be greater than:
def numToBinary(k, n):
''' converts number to binary number bit size k'''
def binary(n):
if n == 0:
return ''
elif n % 2 == 1:
return binary(n//2)+'1'
else:
return binary(n//2) + '0'
temp = binary(n)
if len(temp) <= k:
answer = '0' * (k - len(temp)) + temp
else:
answer = temp[-k:]
return answer
If you wanted to see exactly what was happening you should put a print in you own code, if you added a print(n) in binary you would see a lot of output like:
5.125332723668738e-143
2.562666361834369e-143
1.2813331809171846e-143
6.406665904585923e-144
3.2033329522929615e-144
Which meant you eventually hit the recursion limit.

Resources