When I run the below module, it runs for about 960 recursions:
import matplotlib
import pylab
xStart = 1
debug = 'off'
xList = []
calcList = []
def collatzCalc(xStart,calcs):
calc = 0
xCalc = 0
xCalc = xStart
while xCalc > 0:
if debug == 'on':
print(round(xCalc))
print(xList)
print(calcList)
if xCalc == 1:
xList.append(xStart)
calcList.append(calc)
xStart += 1
if debug == 'on':
print(calcs)
print('---------------------------')
calcs += 1
collatzCalc(xStart,calcs)
else:
if xCalc % 2 == 0:
xCalc = xCalc / 2
calc += 1
else:
xCalc = xCalc * 3 + 1
calc += 1
calcs = 0
collatzCalc(xStart,calcs)
It throws the following error:
Traceback (most recent call last):
File "C:\Users\Erin Lynch\Desktop\collatzConjecture.py", line 49, in <module>
collatzCalc(xStart,calcs)
File "C:\Users\Erin Lynch\Desktop\collatzConjecture.py", line 32, in collatzCalc
collatzCalc(xStart,calcs)
File "C:\Users\Erin Lynch\Desktop\collatzConjecture.py", line 14, in collatzCalc
while xCalc > 0:
RuntimeError: maximum recursion depth exceeded in comparison
I know why this is happening, because I read today about recursion limits, but what I'm wanting to know is how I can turn my recursion formulas into iterative ones. I am completely lost on how to do this, and I need help from someone who knows how.
First of all, in this part, the first line is unnecessary since xCalc
will be immediately overwritten with xStart
:
xCalc = 0
xCalc = xStart
Secondly, if you observe the code carefully, you see that if xCalc
ever reaches 1
it will just loop forever:
def collatzCalc(xStart,calcs):
...
xCalc = xStart
while xCalc > 0:
...
if xCalc == 1:
...
collatzCalc(xStart,calcs)
else:
...
Since xCalc
is a local variable , other instances of collatzCalc
cannot modify this variable. The function will just keep looping forever. While it makes sense to loop forever in the "outermost" function since you're checking the Collatz conjecture, it does not make sense to do it recursively .
I think it's because you have confused two distinct parts of this program:
Let's address the first one because it's easier. To check the Collatz conjecture, you just need a simple loop:
def checkCollatz(xStart=1, debug=False):
xList = []
calcList = []
while True:
calc = collatzCalc(xStart, debug=debug)
xList.append(xStart)
calcList.append(calc)
if debug:
print(xStart - 1)
print('---------------------------')
xStart += 1
Here, I have turned the global variables ( xList
, calcList
, xStart
, and debug
) into local variables of this outermost function. (You might also want to pick more descriptive names for them too.) Note that I have completely eliminated the calcs
variable because it appears to be identical to xStart
, except always lower by one.
Now, to calculate the Collatz sequence, I can reuse what you already have (stripping out the parts that were used in checkCollatz
):
def collatzCalc(xCalc, debug=False):
calc = 0
while xCalc > 0:
if debug:
print(xCalc)
if xCalc == 1:
return calc
else:
if xCalc % 2 == 0:
xCalc = xCalc // 2
else:
xCalc = xCalc * 3 + 1
calc += 1
The use of round
is unnecessary since Collatz sequences are always integers. Additionally, one should use integer division ( //
) instead of floating-point division ( /
) because /
will coerce your numbers into floating-point numbers.
Notice that there is no recursion at all in this code. The recursion has been eliminated and transformed into the loop in checkCollatz
(notice that there are now two while
loops instead of one). Your original code was already mostly iterative so converting it into a recursive one was not very involved.
As a side note, notice that by splitting the function into two separate functions, there are now much fewer variables and the code is a lot easier to read.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.