Reputation: 516
This is my code on the Collatz sequence:
def collatz(a):
while (a != 1):
if a%2 == 0:
a = a//2
print (a, " -> ")
a = collatz(a)
elif a%2 != 0:
a = int(3*a + 1)
print (a, " -> ")
a = collatz(a)
x = int(input("Enter a number: "))
collatz(x)
The output I get is perfect for every number I enter, but Jupyter Notebook also shows some kind of error. Am I making some kind of error in recursion? I've linked the output and error shown.
Upvotes: 0
Views: 63
Reputation: 76234
You do a = collatz(a)
, but since your function has no return statements, this sets a
to None. Then in the next iteration of the loop you try to do arithmetic on a. This fails, because you can't do arithmetic on None.
You don't really need recursion here at all. You already have a loop, so you can simply delete those collatz calls.
def collatz(a):
while (a != 1):
if a%2 == 0:
a = a//2
print (a, " -> ")
elif a%2 != 0:
a = int(3*a + 1)
print (a, " -> ")
x = int(input("Enter a number: "))
collatz(x)
... But if you're dead-set on having recursion, you can do that too. Delete the while loop, and call collatz
at the end of your function.
def collatz(a):
if a == 1:
return
if a%2 == 0:
a = a//2
elif a%2 != 0:
a = int(3*a + 1)
print (a, " -> ")
collatz(a)
The drawback of this approach is that it will crash with "maximum recursion depth exceeded" if the function recurses more than 999 times. Collatz sequences converge to 1 fairly quickly, so this probably isn't a practical problem for this specific algorithm, but it's something to keep in mind when writing any recursive function.
Both of these approaches have the potentially undesirable behavior of printing "->" after the final number in the sequence. This is a fairly common problem in this style of "print-while-iterating" code. One possible solution is to remove the print calls from the function, instead returning a list of the values of the sequence. Then you can style your output after the fact, using join
to intersperse the numbers with arrows.
def collatz(a):
result = [a]
while (a != 1):
if a%2 == 0:
a = a//2
elif a%2 != 0:
a = int(3*a + 1)
result.append(a)
return result
x = int(input("Enter a number: "))
seq = collatz(x)
print(" -> ".join(str(num) for num in seq))
Upvotes: 1