Use Recursion to Create a Countdown: what is really happening in that code?

Hi everybody.

I resolved the challenge and I understood the idea. I have already studied recursion in my graduation. But, I want to understand what is happening when the recursion “stack” is returning, step to step.

Could anyone please tell me if you know some “recursion unstacking drawer”? :slight_smile:
Thank you.


// Only change code below this line
function countdown(n){
if (n < 1) {
  return [];
} else {
  const countArray = countdown(n - 1);
  countArray.unshift(n);
  return countArray;
}
}
console.log(countdown(10));
// Only change code above this line
  **Your browser information:**

User Agent is: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36

Challenge: Use Recursion to Create a Countdown

Link to the challenge:

When in doubt, add more console logs

function countdown(n) {
  console.log("called countdown(" + n + ")");
  if (n < 1) {
    console.log("  base case");
    console.log("    returning: []");
    return [];
  } else {
    console.log("  recursive case");
    console.log("    calling countdown(" + (n - 1) + ")");
    const countArray = countdown(n - 1);
    console.log("    returned from countdown(" + (n - 1) + ") with", countArray);
    console.log("    unshifting " + n);
    countArray.unshift(n);
    console.log("    returning:", countArray);
    return countArray;
  }
}
console.log("final result:", countdown(10));

Hi @cgf04df,

IDK if this is what are you looking for, but I think that python tutor is really useful:

https://pythontutor.com/live.html#mode=edit

I also wrote a short faq about recursion (is not the same exercise but I think is similar enough, look at: 5.- Why I'm Getting [4,3,2,1] ? ):

code

function rangeOfNumbers(startNum, endNum) {
   if(startNum === endNum) {  
     return [endNum]; 
   } else {  
     let arr =  rangeOfNumbers(startNum + 1, endNum); 
     arr.push(startNum); 
     return arr;     
   }
}

let result = rangeOfNumbers(1,4);
console.log(result);
// [ 4, 3, 2, 1 ]

1.- What happens when the base case is evaluated as false?

The function calls itself:
Steps: 4,6,8

2.- What happens when the base case is evaluated as true?

Returns an array:
Step: 10

3.- The Array, where does it come from?

From the base case:
Step: 10

4.- Why can I push startNum to arr?

Because after the base case is evaluated as true, arr is an array:
Step: 11

5.- Why I’m Getting [4,3,2,1] ?

Because JavaScript uses a “stack” (LIFO, last in first out):
Steps: 10, 13, 16, 19

6.- How can I get [1,2,3,4]?

Replace push with unshift

function rangeOfNumbers(startNum, endNum) {
   if(startNum === endNum) {  
     return [endNum]; 
   } else {  
     let arr =  rangeOfNumbers(startNum + 1, endNum); 
     arr.unshift(startNum);  // <-  here  
     return arr;     
   }
}

let result = rangeOfNumbers(1,4);
console.log(result); 
// [ 1, 2, 3, 4 ]

7.- Related topics:

  • nested (function) calls
  • call stack

8.- You can use python tutor to see step by step how the function is executed:

https://pythontutor.com/live.html#mode=edit

Cheers and happy coding :slight_smile:

Notes:

  • A demo of python tutor:
  • If you know spanish, I recorded a video explaining recursion step by step:
  • I also wrote a blog post (it has 27 images)

https://diegoperezm.github.io/blog/recursion.html

  • Other things about recursion:

    • Recursividad: primero y resto (Spanish)