1

I'm supposed to write code that shows the collatz conjecture in 3 different ways for an assignment using recursion. If you're not familiar with the idea, the conjecture states that if you take any starting value n you can ultimate get to the value of 1 by dividing n/2 if n is even or multiplying 3n + 1 if n is odd. I'm supposed to show a completed algorithm in 3 ways, forwards, backwards, and in a palindrome fashion.

For example, the value 32 in the forward fashion would show : 32 16 8 4 2 1

The value 32 in the backwards fashion would show 1 2 4 8 16 32

Finally, the palindrome fashion would show 32 16 8 4 2 1 2 4 8 16 32

I have been able to get forwards and backwards completed but the palindrome part is slipping me up. All my efforts have either shown the forward fashion or gotten me stuck in an infinite loop.

*IMPORTANT * Here's the tricky part: I'm not allowed to declare any local or global variables to help me with the problem. I am only allowed to use the original arguments of the Collatz method, loops, and recursion. Does anyone have a solution for this trickster?

def Collatz(number , algorithm):
    if number == 1:
        print number
        return
    if algorithm == 'F':
        if number % 2 == 1:
            print number
            Collatz((3*number) + 1, algorithm)
        if number % 2 == 0:
            print number
            Collatz((number/2),algorithm)
    if algorithm == 'B':
        if number % 2 == 1:
            Collatz((3*number) + 1, algorithm)
            print number
        if number % 2 == 0:
            Collatz((number/2),algorithm)
            print number
    **if( algorithm == 'P'):**

m = input( "Enter a positive integer value: " )
displaymode = ''  # initialize to anything not F, B, P
while displaymode not in ['F', 'B', 'P']:
    displaymode = raw_input( "Choose a display mode:  F=forward, B=backward,   P=palindrome: " )
Collatz( m, displaymode )
print 
Eli Sadoff
  • 7,173
  • 6
  • 33
  • 61
Caladin00
  • 356
  • 1
  • 3
  • 11
  • It's probably to force people to embrace the one true path to recursion.. – Iluvatar Dec 09 '16 at 00:08
  • Honestly, in this case, not using local or global variables makes sense. If you want to print it forwards, you print the number, then do the rest. If you want to do it backwards, you do the rest, then print the number. The palindrome is simply doing both. – Reed Oei Dec 09 '16 at 00:09
  • 1
    I see what they are trying to force you to do now... – juanpa.arrivillaga Dec 09 '16 at 00:13
  • Some stylistic advice, those commas are completely unnecessary. Essentially the create a tuple that will never be captured. Also, parentheses are not necessary in your `if` conditions (unless they serve to force some order of operation). – juanpa.arrivillaga Dec 09 '16 at 00:16
  • I hate recursion exactly for this reason XD – Caladin00 Dec 09 '16 at 00:25
  • Note that if the same code goes in an `if` and an `else`, and it doesn't depend on or affect the rest of the code in those blocks, then it can go outside. I.e., you can move `print number,` above or below the `if-else`, as appropriate. – BallpointBen Dec 09 '16 at 00:49

1 Answers1

1

So as you've figured out, putting the print statement before the recursive step shows the forward case. And putting the print statement after the recursive step shows the backward case. Now how would you show the palindrome case, which is showing the forward steps and then the backward steps...

To continue, what you're doing in the forward case is continuously calling Collatz. Each time you do this, you get the next number in the sequence, and you go down a level of recursion. You print out the number before going down, and thus you get something like this:

time -->

number=8
   |   \
   |   number=4
   |      |   \
   |      |   number=2
   |      |      |   \
   |      |      |   number=1 (base case)
   |      |      |      |
   8      4      2      1   (what's printed out)

8 4 2 1 printed out in that order

In this diagram, downward represents going a layer deeper recursively. Each vertical slice shows the value of the Collatz function that is running code at that time.

Once you reach the base case, then you return, and finish executing the functions. Each of the functions you 'passed through' regains control and continues executing. In the forward case, nothing happened. In the backward case, however, you printed after recursing, leading to something like this happening:

number=8                                  number=8
       \  (n=8) waiting for Collatz...    /  |
       number=4                    number=4  |
              \  (n=4) waiting...  /  |      |
              number=2      number=2  |      |
                     \  ... /  |      |      |
                     number=1  |      |      |
                        |      |      |      |      
                        1      2      4      8   (what's printed out)

1 2 4 8 printed out in that order

Hopefully this makes it a bit more clear about what's going on, and about how to do the palindrome version.

Iluvatar
  • 1,537
  • 12
  • 13
  • That's exactly where I've gotten lost unfortunately.. If the value number reaches 1, the program defaults to the top and ends on the return statement.... – Caladin00 Dec 09 '16 at 00:16
  • ... and something else keeps happening – juanpa.arrivillaga Dec 09 '16 at 00:17
  • 1
    But it doesn't quite end there, a fact that you take advantage of in the backward case. – Iluvatar Dec 09 '16 at 00:17
  • Still don't see it... I feel like I need to add another recursive statement somewhere but I'm not sure where exactly. – Caladin00 Dec 09 '16 at 00:26
  • I think I'm getting warmer. So... you need to go back up a recursive layer? – Caladin00 Dec 09 '16 at 00:44
  • The way recursion works, you go down a bunch of layers, and then once you reach the base case you go back up all your layers. Look at the second diagram. Every `number=x`, that level function has control and can execute code. So, first the function with `number=8` does stuff, then `number=4`, and so on, down to `number=1`. THEN, it goes back up, so `number=2` does stuff, etc, all the way to the function call where `number=8` does stuff. – Iluvatar Dec 09 '16 at 00:49
  • Got it! You put print number on both sides of the recursive method call. Thanks for the help man. – Caladin00 Dec 09 '16 at 00:51
  • Yes, you got it! Also, give recursion a second chance, it isn't so bad :P – Iluvatar Dec 09 '16 at 00:54