-1

I am trying to create a python script for the collatz conjecture (if a number's odd, times it by three and add 1, and if it's even, divide by two). I can't figure out how to successfully increment a variable that shows how many iterations of the function and I think it has something to do with it being recursive. Here's what I've got so far:

def collatz(n):
    list_terminate = [0, 1, 2, 4]
    if n in list_terminate:
        return n
    else:
        if n % 2 == 0:
            print(n)
            iterations += 1
            return collatz(n // 2)
        if n % 2 == 1:  
            iterations += 1
            print(n)
            return collatz((n * 3) + 1)
Skam
  • 7,298
  • 4
  • 22
  • 31
liam6666
  • 19
  • 1
  • 9

3 Answers3

3

There are a few options...

1) Change the function signature to include the number of iterations. This way, you can pass the information 'up the chain'

2) Change the scope of num iterations such that the variable exists outside the function.

3) Add a recursive function inside collatz.

approach (1, 3)

def collatz(n):

    def recursion(x, iterations):
        print(f"{iterations}: {x}")
        if x in [0,1,2,4]:
            return x, iterations

        if x % 2 == 0:
            return recursion(x//2, iterations + 1)
        else:
            return recursion((x*3) + 1, iterations + 1)

        return n

    n, steps = recursion(n, 0)

approach (2)

iterations = 0
def collatz(n):
    global iterations

    print(f"{iterations}: {n}")
    if n in [0,1,2,4]:
        return n, iterations

    iterations += 1
    if n % 2 == 0:
        return collatz(n//2)
    else:
       return collatz((n*3) + 1)
petezurich
  • 9,280
  • 9
  • 43
  • 57
hamster
  • 76
  • 2
1

The variable does not persist between function calls. If you want to have multiple values passed between functions, then pass it as a parameter to your function and return both.

def collatz(n, iterations):
    list_terminate = [0, 1, 2, 4]
    if n in list_terminate:
        return (n, iterations)
    else:
        if n % 2 == 0:
            print(n)
            iterations += 1
            return collatz(n // 2, iterations)
        if n % 2 == 1:  
            iterations += 1
            print(n)
            return collatz((n * 3) + 1, iterations)

If you don't like calling your function like, collatz(n, 0), then use this is a wrapper function.

def collatz_helper(n, iterations):
        list_terminate = [0, 1, 2, 4]
        if n in list_terminate:
            return (n, iterations)
        else:
            if n % 2 == 0:
                print(n)
                iterations += 1
                return collatz(n // 2, iterations)
            if n % 2 == 1:  
                iterations += 1
                print(n)
                return collatz((n * 3) + 1, iterations)

def collatz(n):
    return collatz_helper(n, 0)
Skam
  • 7,298
  • 4
  • 22
  • 31
1

Your problem statement is little confusing but you may try the below code, if it suits you.

def collatz(n):
    iterations = 0
    list_terminate = [0, 1, 2, 4]
    if n in list_terminate:
        return n
    elif n % 2 == 0:
        # print(n)
        iterations += 1
        return ("No. of iterations : ", iterations, n//2)
    elif n % 2 == 1:
        iterations += 1
        # print(n)
        return ("No. of iterations : ", iterations,(n * 3) + 1)