4

Im trying to understand double recursion but i'm not getting anywhere.

def f(s): if len(s) <= 1: return s return f(s[1:]) + s[0] print f('world') 

dlrow

if am right the above code will do the following:

  1. f(s[1:]) + s[0] ==> f(orld) + w
  2. f(s[1:]) + s[0] ==> f(rld) + o
  3. f(s[1:]) + s[0] ==> f(ld) + r
  4. f(s[1:]) + s[0] ==> f(d) + l <== here len(s) == 1 so s = d,

then:

  1. d + l = dl
  2. dl + r = dlr
  3. dlr + o = dlro
  4. dlro + w = dlrow

so dlrow will be printed as seen above.

I can not understand the code when you make it double recursive:

def f(s): if len(s) <= 1: return s else: return f(f(s[1:])) + s[0] #Note double recursion print f('world') 

Can someone please explain to me how this double recursion works?

7
  • 1
    Have you tried it? What happened? Why not try drawing the same diagram again? Commented Dec 3, 2014 at 22:45
  • The double recursion prints "orldw". the problem is, that i cannot draw a diagram for it.. Commented Dec 3, 2014 at 22:49
  • 1
    You see how long your analysis of the original version is? I assume the analysis of the second version will be twice as long ;-) Commented Dec 3, 2014 at 22:51
  • 1
    Princeton has this fantastic visualization of recursion using the Fibonacci sequence: introcs.cs.princeton.edu/java/23recursion Commented Dec 3, 2014 at 22:52
  • 3
    I suggest you start from the base case: what does calling the function on it twice do? Then build "out". Note that y = f(f(x)) is temp = f(x); y = f(temp). Commented Dec 3, 2014 at 22:54

2 Answers 2

4

Here's an easy way to instrument your recursive code

import inspect def f(s): print " " * (len(inspect.stack())-2), '>>', s if len(s) <= 1: print " " * (len(inspect.stack())-2), '<<', s return s else: retval = f(f(s[1:])) + s[0] #Note double recursion print " " * (len(inspect.stack())-2), '<<', retval return retval print f('world') 

prints

 >> world >> orld >> rld >> ld >> d << d >> d << d << dl >> dl >> l << l >> l << l << ld << ldr >> ldr >> dr >> r << r >> r << r << rd >> rd >> d << d >> d << d << dr << drl << drlo >> drlo >> rlo >> lo >> o << o >> o << o << ol >> ol >> l << l >> l << l << lo << lor >> lor >> or >> r << r >> r << r << ro >> ro >> o << o >> o << o << or << orl << orld << orldw orldw 
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks gribbler, i didn't know about inspect. everything becomes easier when visualized.
But the question "what does this function do" remains. For "world" it returns "orld" + "w". But for other lengths the returned value is more complex. The most peculiar thing I just found out is that f(f(f('123'))) returns '123', f(f(f(f('1234')))) returns '1234' etc. for lengths up to 8. But f(f(f(f(f(f(f(f(f('123456789'))))))))) suddenly returns '283145796'. This is most peculiar.
yes you're right! I was trying the same with "world". I have to play around with it, I will definitely come back to it after i understand what it does.
Good luck. Seems to be a very complex topic. Have a look at pastebin.com/7fbcXZFc where I tried around a little bit.
1

In 2019, using online compilers, such as www.onlinegdb.com/online_python_compiler, the print lines as above do not work. Here is working code:

import inspect def f(s): print(" " * (len(inspect.stack())-2), '>>', s) if len(s) <= 1: print( " " * (len(inspect.stack())-2), '<<', s) return s else: retval = f(f(s[1:])) + s[0] #Note double recursion print( " " * (len(inspect.stack())-2), '<<', retval) return retval print(f('world')) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.