Dynamic Programming: Recursion

    Dynamic Programming: Recursion

      If you've ever moved from one house to another or helped someone else move, you know it involves recursion.

      What's that? You don't know that? Oh yes you do. You just don't know you know it, but we know you know what you don't think you know, so we'll clear it up for you.

      (Then we'll clear up that last statement, too. Maybe.)

      When you move, you have to do all sorts of small tasks over and over again to finish the big task. You can't just move your entire house and call it a day. That would defeat the entire purpose of moving, after all. You have to pack up boxes, lots and lots of boxes. Once they're packed, you have to load them on the truck one at a time.

      When you get to the new place, you have to unload the truck, which means you have to break down the problem of carrying all the boxes into the house into the more manageable problem of carrying in one box at a time. If you keep repeating yourself by carrying in one box from the truck over and over again, you're basically doing something recursively.

      Recursion is a critical topic, so pay attention now because it'll come back over and over, and it's sure to show up on a computer science test sometime. Here are a few other ways to think about it:

      • Recursion is applying the same operation over and over again, breaking it down a little each time, to solve a problem.
      • In math and science, it's a function that has to call itself to find the answer. 
      • Your grandparents had your parents and your parents had you. That's basically breaking the problem of "continuing the human species" into the smaller problem of continuing the human species for another eighty years or so. Recursively.

      A recursive function or procedure calls itself, and it will keep calling itself forever (a little something we like to call an infinite loop) unless you set some conditional criteria to make it stop.

      One of our favorite examples is a factorial function. If you take the factorial of a number, you're actually just multiplying that number to the factorial of the number before it. 4!, for example, breaks down into 4 × 3 × 2 × 1, which equals 24.

      It can also be written as:

      4! = 4 × 3!
      4! = 4 × (3 × 2!)
      4! = 4 × (3 (2 × 1!))
      4! = 4 × (3 × (2 × (1))) = 24

      To solve the factorial function, you have to call the factorial function on smaller and smaller numbers until it reaches the base case, which ends that infinite spiral.

      Most recursive functions

      • return a function—usually the same one. 
      • have a base case that ends the function.
      • offer recursive steps that break the problem down towards that base case.

      The recursive code for the factorial function looks like this:

      method definition
      	Given some base case
      		Do something
      	Otherwise
      		Call to same method recursively

      When this code runs, it stores intermediate results from the active function in the computer's call stack—its stack of currently-running functions. Before the computer can fill in the correct value for n factorial, it needs to wait for the call stack to return the result of n – 1 factorial. That keeps drilling down and down until the call stack hits that base case and fills in the values at every level of the call stack.

      Wait, what?

      Let's look a little more thoroughly into the factorial example. Each pass through our factorial subroutine puts the current function result onto a stack. We'll let n =4 because it seems like a nice number.

      Iteration 1: n = 4 and is not equal to 1, so FACTORIAL(4) = 4*FACTORIAL(3) goes onto the stack

      Iteration 2: n = 3 and is not equal to 1, which means FACTORIAL(3) = 3*FACTORIAL(2) goes onto the stack

      Iteration 3: n = 2 and is not equal to 1, meaning that FACTORIAL(2) = 2*FACTORIAL(1) goes onto the stack

      Iteration 4: n = 1 and is equal to 1, meaning that—wait for it—1 is returned

      Now that FACTORIAL(1) actually returned something without calling something else, we can start filling those empty method calls with real values.

      Unstack iteration 4: n =1
      FACTORIAL(1) = 1

      Unstack iteration 3: n = 2
      FACTORIAL(2) = 2*FACTORIAL(1) = 2

      Unstack iteration 2: n = 3
      FACTORIAL(3) = 3*FACTORIAL(2) = 6

      Unstack iteration 1: n = 4
      FACTORIALS(4) = 4*FACTORIAL(3) = 24

      And there you have it. The result of 4! is 24.

      Recursion can simplify the code, but it can also use large amounts of CPU time, depending on just how many recursive calls it makes.

      Imagine standing two big mirrors so they face each other. If you step in between those two mirrors, you'll end up looking at infinite copies of yourself on both sides With the infinite number of reflections, you might have just recursively immortalized yourself.

      Don't forget to take a shot of it and upload it to Instagram.