Problems with the test cases on the recursive Countdown challenge

Hi folks,

I trying to solve this exercise.

I usually do not use FCC’s environment to build my code. Instead, I like to use VSCode or Vim for editing and ubuntu’s terminal to run the code. In addition, I am using nodejs to interpret the JS code.

This is my code:

function countDown(n) {
  if (n<1) {
    return [];
  }
  else if (n==1) {
    array.push(n);
    return array;
  }
  else {
    array.push(n);
    return (countDown(n-1));
  }
}

//console.log(countDown(10));
//console.log(countDown(5));
console.log(countDown(-1));
console.log(countDown(10));

In my machine this seems to work. Why this code is not passing on the platform test cases?

Thanks in advance.

You are relying upon some undeclared global variable instead of using true recursion.

Your code contains global variables that are changed each time the function is run. This means that after each test completes, subsequent tests start with the previous value. To fix this, make sure your function doesn’t change any global variables, and declare/assign variables within the function if they need to be changed.

Example:

var myGlobal = [1];
function returnGlobal(arg) {
  myGlobal.push(arg);
  return myGlobal;
} // unreliable - array gets longer each time the function is run

function returnLocal(arg) {
  var myLocal = [1];
  myLocal.push(arg);
  return myLocal;
} // reliable - always returns an array of length 2

You also never declared your variable array (which is a very bad name for an array, you should use a different name), which also causes errors. It is a best practice to declare all variables.

2 Likes

Hi,

Thanks for helping. My first attempt was something close to your suggestion.

However, when I use the local approach the array keeps being redefined over each recursive call.

Check-it out:

function countDown(n) {
  var countDownList = [];

  if (n<1) {
    return [];
  }
  else if (n==1) {
    countDownList.push(n);
    return countDownList;
  }
  else {
    countDownList.push(n);
    return (countDown(n-1));
  }
}

The console returns:

console.log(countDown(-1)); // console returns [] which is right
console.log(countDown(10)); //  console returns [1] which is WRONG
console.log(countDown(5)); // console returns [1] which is WRONG

The wrong results happen due to the redefinition problem that I described.

How should I use the local scope suggestion AND avoid this problem?

Thanks in advance.

If I had total freedom to solve this, I would do a LISP approach: storing the temporary variable as one of the parameters:


function countDown(n,listaTemp) {

  if (n<1) {
    return [];
  }
  else if (n==1) {
    listaTemp.push(n);
    return listaTemp;
  }
  else {
    listaTemp.push(n);
    return (countDown(n-1,listaTemp));
  }
}


console.log(countDown(-1,[]));
console.log(countDown(10,[]));
console.log(countDown(5,[]));

It seems to work perfectly. But you need to change the input for the test cases.

You can use that approach by using default parameter values, but you don’t need to. One of the things that trips people up about this lesson is that they forget that the function always returns an array!

Look at the example again

function countup(n) {
  if (n < 1) {
    return []; // This is an array
  } else {
    const countArray = countup(n - 1); // Here the return value (an array) is used
    countArray.push(n);
    return countArray; // This is an array
  }
}
console.log(countup(5)); // [ 1, 2, 3, 4, 5 ]
1 Like

Hi,

I used the approach above with the default parameter. However, for some reason the code was not passing on the tests.

Hence, I decided to go for something like you suggested:

function countdown(n) {
  if (n < 1) {
    return [];
  } else {
    const countArray = countdown(n - 1);
    countArray.unshift(n);
    return countArray;
  }
}

This approach passes on the tests and it is just like the example provided.
However, I am using unshift(). I am insecure about the unshift().

Am I cheating the exercise purpose due to the unshift()?

Unshift is a great choice here. It is exactly what I would have used. I think your solution works great.

By the way, what I meant by default parameter values is

function countDown(n,listaTemp = []) {
1 Like