0

For the case, the sequence does not end in 1. How can I create a code that has some way of stopping the execution if 1 is not reached after a certain number of iterations? I just don't know how to add this to my code below. And is there a way to make it work with a list of divisors such as [2, 3]? I'm using Python.

import numpy

#change the function to have 3 input args, the number, the multiplier and the 
divisor
def collatz(n,multiplier,divisor):
    list1 = [n]
    if n == 1 :
        return [1]   
    elif n % 2 and n % 3 == 0 :
        #edit the function's input args for both the else and elif loops
        list1.extend(collatz(n//divisor,multiplier,divisor))   
    else:
        list1.extend(collatz(n*multiplier+1,multiplier,divisor))  
    return list1

#driver function to get the input number, multiplier and divisor
if __name__=="__main__":
    n=int(input("Enter any positive integer N: "))
    multiplier=int(input("Enter the multiplier: "))
    divisor=int(input("Enter the divisor: "))

    print("\n",collatz(n,multiplier,divisor))

2 Answers2

0

You will get a stack overflow error after ~1000 recursions I believe.The way to override this: https://stackoverflow.com/a/3323013/10875953. But 2^64 is immensly large, you won't be able to do that. Rather try making a iterative function.

Robin Dillen
  • 704
  • 5
  • 11
0

You should use your divisor parameter in the condition that select the operation on the number.

To make this easier to manage, you shouldn't use recursion. A simple while loop will suffice:

def collatz(n,divs=2,mult=3,inc=1,maxSize=-1):
    result = []
    while n not in result and len(result)!=maxSize:
        result.append(n)
        n =  (n*mult+inc)if n%divs else n//divs
    return result + ['...']*(n not in result)

output:

print(collatz(20))
[20, 10, 5, 16, 8, 4, 2, 1]

print(collatz(30,2,6,2,maxSize=10))
[30, 15, 92, 46, 23, 140, 70, 35, 212, 106, '...']

print(collatz(30,2,6,2))
[30, 15, 92, 46, 23, 140, 70, 35, 212, 106, 53, 320, 160, 80,
 40, 20, 10, 5, 32, 16, 8, 4, 2, 1]

print(collatz(30,2,5,3))
[30, 15, 78, 39, 198, 99, 498, 249, 1248, 624, 312, 156]

print(collatz(60,4,3,-2,maxSize=10))
[60, 15, 43, 127, 379, 1135, 3403, 10207, 30619, 91855, '...']
Alain T.
  • 40,517
  • 4
  • 31
  • 51
  • Hello, Thank you very much for your answer it really helped!!! Thank you! – user17511022 Jan 19 '22 at 17:31
  • But is there a way we can have multiple divisors? For example like this: collatz(30,[2,3,5],6,1,maxSize=64). Where we can choose what kind of divisors we want to put in. – user17511022 Jan 19 '22 at 17:32
  • Sure. How to do it will depend on how you want to use them. For example, if you want to check if the number is divisible by any of them you could make the condition `all(n%d for d in divisors)`. You may need extra parameters (or logic) to chose which divisor to use to reduce `n`. All up to you. – Alain T. Jan 19 '22 at 17:37