Maximum recursion, GCD(greatest common divisor) - python

I wrote a program to find gcd using python.
def gcd(a,b):
r=a%b
if r==0:
return a
elif r==1:
return 1
else:
gcd(a,b)==gcd(b,r)
return gcd(b,r)
Whenever I call the function it shows the message "Max. recursion exceeded." Please help
I know it can be done using looping but I want to specifically do it by using recursion method. And bear with me. I am a learner!

This statement is unnecessary and it's the one making the recursion endless: gcd(a,b)==gcd(b,r) because it's calling gcd(a,b) again and again. Just remove it:
def gcd(a,b):
r=a%b
if r==0:
return a
elif r==1:
return 1
return gcd(b,r)
Note: By the way, you got the formula wrong, you should return b on the if clause since you're dividing a/b when calculating the modulo.
def gcd(a,b):
r=a%b
if r==0:
return b
elif r==1:
return 1
return gcd(b,r)
>>>gcd(10,4)
2

If you're trying to calculate the GCD of very large numbers (e.g., when searching for common factors in RSA moduli), you might be better off avoiding recursion altogether and using an iterative function instead. For example:
def gcd(a,b):
while a:
a,b = b%a,a
return b

gcd(a,b)==gcd(b,r) doesn't do what you expect it to do.
It doesn't mean "define gcd(a,b) to be equal to gcd(b,r)".
Instead, gcd(a,b)==gcd(b,r) means:
Compute gcd(a,b)
Compute gcd(b,r)
Compare the two results and see if they're equal.
Since you're asking to compute gcd(a, b) in order to compute gcd(a, b), you'll get an endless recursion.
Instead, you want the return gcd(b, r) at that point. I.e.:
def gcd(a,b):
r=a%b
if r==0:
return a
elif r==1:
return 1
else:
return gcd(b,r)

This is how I did it
def gcd(m,n):
if m >= n:
r = m % n
if r == 0:
return n
else:
m = n
n = r
return gcd(m,n)
else:
temp = m
m = n
n = temp
return gcd(m,n)

def gcd(a,b):
if a % b == 0:
return b
return gcd(b, a % b)

Related

Fibonacci summing and memoization [duplicate]

This question already has answers here:
Sum of Even Fibonacci Numbers < X
(5 answers)
Closed 2 years ago.
I'm taking a programming course and there's a question about fibonacci sums and recursion.
the rules are as follows:
Write a function fibsum(N) that returns the sum of all even valued fibonacci terms that are less than N.
I've gotten close I think but my summation isn't working properly, also I'd like the function to work up pretty high (like N = 10**6 at least), here's my code so far
def fibsum(n, memo = {}):
added = 0
if n<0:
return 0
if n== 1 or n == 0:
return 1
else:
if (n-1) in memo.keys():
f1 = memo[n-1]
else:
memo[n-1] = fibsum(n-1)
f1 = memo[n-1]
if (n-2) in memo.keys():
f2 = memo[n-2]
else:
memo[n-2] = fibsum(n-2)
f2 = memo[n-2]
if f1+f2 < 44:
if (f1+f2) % 2 == 0:
added += f1+f2
print ("look here",added)
return added
print (f1+f2)
return f1 + f2
I've left some print statements because I was trying to debug the problem but I've had no luck.
edit: I've been linked another question but it is done iteratively in that case, I would like to do it recursively if possible
memoization wont help you with large values for fib
but as an aside seperate your logic
def fib(n):
"""
simple recursive fibonacci function
"""
if n == 0:
return 1
return n + fib(n-1)
then make a generic memoization decorator
def memoize(fn):
cache = {}
def _tokenize(*args,**kwargs):
return str(args)+str(kwargs)
def __inner(*args,**kwargs):
token = _tokenize(*args,**kwargs)
if token not in cache:
cache[token] = fn(*args,**kwargs)
return cache[token]
now just decorate your simple recursive function
#memoize
def fib(n):
"""
simple recursive fibonacci function
"""
if n == 0:
return 1
return n + fib(n-1)
now you can make your fibsum method (and also memoize it)
#memoize
def get_fib_nums(n):
if n == 0:
return [1]
return [n] + get_fib_nums(n)
#memoize
def fibevensum(n):
return sum(n for n in get_fib_nums(n) if n%2 == 0)

Even valued terms sum in fibonacci, limit is 4 million

def fib(n):
if n<= 1:
return n
else:
return(fib(n-1)+fib(n-2))
def comp():
L=[]
for i in range(1,4000000):
if i % 2 ==0:
L.append(fib(i))
return sum(L)
print(comp())
What is wrong with this code? It does not return anything but it looks good according to me.
you should return sum(L) from function not from for loop follow below code
def fib(n):
if n<= 1:
return n
else:
return(fib(n-1)+fib(n-2))
def comp():
L=[]
for i in range(1,20):
if i % 2 ==0:
L.append(fib(i))
return sum(L)
print(comp())
and other thing look at the range its too much,because of this it will take some time or may produce any memory related error, so reduce it for testing.
The return statement is set to the wrong increment. It is executed the first time i % 2 == 0 becomes true (which is i == 2 in your case).
def fib(n):
if n<= 1:
return n
else:
return(fib(n-1)+fib(n-2))
def comp():
L=[]
for i in range(1,4000000):
if i % 2 ==0:
L.append(fib(i))
return sum(L)
print(comp())
The above code is not going to work, though. Are you aware of how big this number would get?
Try
for i in range(1,40):
as a start. It took quite a few seconds on my machine. Result is 63245985.

Unable to return in if block while calculating GCD [duplicate]

This question already has answers here:
Python recursive function returning none after completion
(3 answers)
Closed 4 years ago.
I am trying to calculate a GCD of 2 numbers, the following code block works fine, I am using recursion, but when I am trying to return a value I am not able to do so, return a results in None
def gcd(a,b):
if b == 0:
print a
return a # This is not working
else:
gcd(b,a%b)
XX = gcd(3, 5)
print (XX)
Output:
1
None
Your code
def gcd(a,b):
if b == 0:
print a
return a # This is not working
else:
gcd(b,a%b)
XX=gcd(3,5)
print (XX)
will not work, because you are missing the return statement in the line gcd(b,a%b). So it should be
def gcd(a,b):
if b == 0:
print a
return a
else:
return gcd(b,a%b)
print(gcd(12, 4))
By the way - if possible, don't code things yourself, use the predefined library:
from fractions import gcd
print(gcd(4, 12))
Your recursion will not work... you are missing a return statement and also the algorithm does not work...
This is what a recursive gcd could look like:
def gcd(a,b):
r = a % b
if r == 0:
return a
elif r == 1:
return 1
return gcd(b, r)
and here a non-recursive gcd:
def gcd(a, b):
while b:
a, b = b, a % b
return a
also note that you could just use math.gcd.

Function would not return value, instead it returns "None"

Please help me look at this piece of code which was supposed to calculate the greatest common division between two numbers (a, b). The problem I'm having is that the program would not return c as expected, instead it return None. But when I use a print statement, it prints out the value of c.
This is my code:
def gcd(a, b):
if a == 0:
return b
elif b == 0:
return a
elif a > b:
big, small = a, b
else:
big, small = b, a
c = big % small
if c == 0:
print(small)
return small
gcd(small, c)
print(gcd(1071, 462))
Thanks guys.
Python implicitly returns None when no explicit return is encountered and the function body ends.
In your case if it passes through all other cases it just hits:
gcd(small, c)
return None # you haven't put that in explicitly but that's how Python processes it
So you probably just need to change the last line to:
return gcd(small, c)

How this greatest common divisor (gcd) works in python

I have taken a piece of code from http://www.s-anand.net/euler.html, problem 5:
def gcd(a,b):
print a,b
return b and gcd(b, a % b) or a
print gcd(10,20)
Giving output:
10 20
20 10
10 0
10
Why the last line prints only "a" not b.
Can you please explain how the return statement in above code works.
I am little bit confused with "and" and "or" operators.
b and gcd(b, a % b) or a
was the old way of writing:
gcd(b, a % b) if b else a
Python's and and or operators use a type of short-circut evaluation that is a little confusing at first.
If they were written as function, they would work sort-of like this, except that they don't even evaluate the right value unless they need to.
def and(left, right):
if left:
return right
else:
return left
def or(left, right):
if left:
return left
else:
return right
So the line return b and gcd(b, a % b) or a could be written more verbosely as:
if b:
temp_1 = gcd(b, a % b)
else:
temp_1 = False
if temp_1:
return temp_1
else:
return a
If you work out the logic, this is equivalent to the common method for finding a GCD. However, unless you're already familiar with Python this code will be hard to read, so you might want to avoid this style.
Because 10 is the greatest common divisor in your case, e.g. result of gcd(10,20)
Your code(return b and gcd(...) or a) is the same as:
def gcd(a,b):
print a,b
if b:
return b
else:
res = gcd(b, a % b)
return res if res else a
Also note that there gcd method in fractions module:
from fractions import gcd
print gcd(10,20)

Categories