-2

Here is my code:

def isEven(number):
    return number % 2 == 0

def run(x):
    z = x
    while z != 1:
        if isEven(z) == True:
            z = z/2
            print z
        else:
            z = (3*z)+1
            print z
    else:
        print 'Got one!'
        #To see if the collatz does indeed always work
    x+=1

It works up until 999, at which it continues indefinitely, print Got one! 999, eventually raising a Segmentation Fault: 22. How do I fix this?

A.J. Uppal
  • 19,117
  • 6
  • 45
  • 76
  • 2
    Where does `x` come from? Full stack trace? Also as you never `break` your loop, you will always enter the `else`. – Hyperboreus Feb 06 '14 at 05:43
  • "Got one!" - got a what? What are you trying to get? What does that message mean? – user2357112 Feb 06 '14 at 05:49
  • How can you say that this snippet "works up until 999", if you assign the local variable x to z, before defining x itself... – Hyperboreus Feb 06 '14 at 05:50
  • And where does the `999` come from, anyway? Your `print` statement doesn't print any numbers. Can you make sure the code you post actually demonstrates the behavior your question is asking about? – user2357112 Feb 06 '14 at 05:58

2 Answers2

1

Here's a cleaner version:

def collatz(x):
    yield x
    while x > 1:
        if x & 1:
            # x is odd
            x = 3*x + 1
            yield x
        # x is now even
        x //= 2
        yield x

def main():
    for x in xrange(2, 5000):
        print('-'*20)
        print(','.join(str(c) for c in collatz(x)))

if __name__=="__main__":
    main()
Hugh Bothwell
  • 55,315
  • 8
  • 84
  • 99
-2

Use a sys.setrecursionlimit to stop the 999 from repeating forever. Here is an edited version of your code. I put a sys.argv[] as well, just for fun because I imported sys. The sys.argv[] gets the argument after you run your program like this: python myscript.py 13.5 In this, sys.argv[1] is 13.5. I set the recursion limit pretty high, but the downfall of this is that the Segmentation Fault: 22 still occurs, and I haven't found a way to get rid of that.

import time
import sys
while True:
    try:
        var = int(sys.argv[1])
        break
    except IndexError:
        print 'You have to enter a number!'
        var = int(raw_input('Enter a number: '))
        break

def check(x):
    z = x
    try:
        while z != 1:
            if isEven(z) == True:
                z = z/2
                print z
            else:
                z = (3*z)+1
                print z


        else:
            print 'Got one!'
            x = x+1
            print 'Trying for %d...' %(x)
            check(x)
    except:
        print 'You were at number %d' %(x)
        check(x)

def isEven(number):
        return number % 2 == 0

sys.setrecursionlimit(10000000)
check(var)
A.J. Uppal
  • 19,117
  • 6
  • 45
  • 76
  • 2
    The OP's posted code isn't even recursive. Do you have access to a more representative version of the OP's code? – user2357112 Feb 06 '14 at 05:59
  • 1
    Also, `sys.setrecursionlimit` is not a solution to stack overflows. Unless you know exactly what you're doing, it just turns a Python stack overflow into a C stack overflow. The correct fix for recursion limit problems is generally to use an iterative solution. – user2357112 Feb 06 '14 at 06:01
  • Well, it worked for me! :) –  Feb 06 '14 at 06:08
  • This is funny. Even if the Collatz conjecture were false, THIS program would never find the proof... – Hyperboreus Feb 06 '14 at 06:16