I need to write a python script that counts the number of times these operations: +, -, *, //, %, >, <, ==, <=, >= are performed in a piece of python code relative to the input of N.
Python Code:
def bar(k):
score = 0
for i in range(2, k + 1):
j = i - 1
while j > 0:
if i % j == 0:
score = score // 2
else:
score = score + 10
j = j - 1
return score
mod = 10**9 + 7
def foo(n):
m = n % 3
if n == 0:
return 1
elif m == 0:
v = foo(n // 3)
t = 0
for i in range(1, n+1):
t = t + bar(4 * i)
return v + t
elif m == 1:
v = foo(n - 1)
return v + bar(n * n * n)
else:
v = foo(n - 2)
r = 1
for a in range(2, n):
r = r * a % mod
r = r + bar(n)
return v + r
My Script:
def count_operations(n):
if n == 0:
return 1 # Base case: 1 operation for returning 1
elif n % 3 == 0:
return count_operations(n // 3) + 4
elif n % 3 == 1:
return 6 + count_operations(n - 1) + 4
else:
return 9 + 2 * count_operations(n - 2)
I wrote the script with the understanding of when N=1,calculating m=1 % 3 takes 1 operation, and the value of m is 1. Then the code executes 3 tests of the == operation before finding one to be true, when it encounters elif m == 1:. Up to that point, 4 operations have been performed.
Then it performs a recursive call with foo(n-1) which means that 5 operations have now been performed before the recursive call (the last for the -). The recursive call now has n=0, so 2 more operations occur (n%3 and n==0), before it returns with its result of 1. That makes a total of 7 basic operations that have now been performed to the point of returning from the recursive call to foo.
The code next encounters return v + bar(nnn), which means that 2 more operations (both *) occur before the call to bar followed by 1 more (+) afterwards, to bring the total 10, not counting the number done in bar. Simulating the call to bar(1), 1 more operation (k+1) is performed when the top end of the range of the for loop is calculated, bringing the total to 11. The for loop terminates immediately since the range of its iteration is empty, and the score of 0 is returned to complete the (already counted) + operation and return statement in foo. So, that means a total of 11 basic operations were performed, and we return 11 as the answer for when N=1.
So, my script only works correctly when n=1 anyone can help me fixed my script to get an understanding of how to do the proper counting when N>1?
My inefficient code what produces the correct answer:
class Integer(int):
n_ops = 0
def new_patch(name):
def patch(self, *args):
Integer.n_ops += 1
value = getattr(int, name)(self, *args)
if isinstance(value, int) and not (value is True or value is False):
value = Integer(value)
return value
patch.__name__ = name
return patch
methods = {
'__le__': '\u2264',
'__lt__': '<',
'__ge__': '\u2265',
'__gt__': '>',
'__eq__': '==',
'__add__': '+',
'__sub__': '-',
'__mul__': '*',
'__floordiv__': '//',
'__mod__': '%',
}
for name in methods:
setattr(Integer, name, new_patch(name))
def bar(k):
score = 0
for i in range(2, k + 1):
j = i - 1
while j > 0:
if i % j == 0:
score = score // 2
else:
score = score + 10
j = j - 1
return score
mod = 10**9 + 7
Integer.n_ops+=1
def foo(n):
m = n % 3
if n == 0:
return 1
elif m == 0:
v = foo(n // 3)
t = 0
for i in range(1, n+1):
t = t + bar(4 * i)
return v + t
elif m == 1:
v = foo(n - 1)
return v + bar(n * n * n)
else:
v = foo(n - 2)
r = 1
for a in range(2, n):
r = r * a % mod
r = r + bar(n)
return v + r
def countOps(n):
print(f'Number of operations when n={n}: {Integer.n_ops}')
m=n%3, m will be either 0, 1, or 2. Why are you then performing further modulo operations on m? It's not necessarily wrong, but it is confusing and wasteful.