Files
freeCodeCamp/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/use-recursion-to-create-a-countdown.md
abe 4ab1dd8926 fix(curriculum): recursion challenges that abuse global space (#47680)
* fix: recursion challenges that abuse global space #43516

* fix challenge phrasing and create separate test

* fix: challenges which pollute/impure functions should not pass

* Update curriculum/challenges/english/02-javascript-algorithms-and-data-structures/javascript-algorithms-and-data-structures-projects/cash-register.md

allow users to ab(use) global space in cash register

Co-authored-by: Tom <20648924+moT01@users.noreply.github.com>

* Update curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/build-a-roman-numeral-converter-project/roman-numeral-converter.md

allow users to abuse global space in roman numeral converter

Co-authored-by: Tom <20648924+moT01@users.noreply.github.com>

Co-authored-by: kravmaguy <flex4lease@gmail.com>
Co-authored-by: Tom <20648924+moT01@users.noreply.github.com>
2022-10-12 15:00:24 -05:00

100 lines
3.4 KiB
Markdown

---
id: 5cd9a70215d3c4e65518328f
title: Use Recursion to Create a Countdown
challengeType: 1
forumTopicId: 305925
dashedName: use-recursion-to-create-a-countdown
---
# --description--
In a <a href="/learn/javascript-algorithms-and-data-structures/basic-javascript/replace-loops-using-recursion" target="_blank" rel="noopener noreferrer nofollow">previous challenge</a>, you learned how to use recursion to replace a `for` loop. Now, let's look at a more complex function that returns an array of consecutive integers starting with `1` through the number passed to the function.
As mentioned in the previous challenge, there will be a <dfn>base case</dfn>. The base case tells the recursive function when it no longer needs to call itself. It is a simple case where the return value is already known. There will also be a <dfn>recursive call</dfn> which executes the original function with different arguments. If the function is written correctly, eventually the base case will be reached.
For example, say you want to write a recursive function that returns an array containing the numbers `1` through `n`. This function will need to accept an argument, `n`, representing the final number. Then it will need to call itself with progressively smaller values of `n` until it reaches `1`. You could write the function as follows:
```javascript
function countup(n) {
if (n < 1) {
return [];
} else {
const countArray = countup(n - 1);
countArray.push(n);
return countArray;
}
}
console.log(countup(5));
```
The value `[1, 2, 3, 4, 5]` will be displayed in the console.
At first, this seems counterintuitive since the value of `n` *decreases*, but the values in the final array are *increasing*. This happens because the push happens last, after the recursive call has returned. At the point where `n` is pushed into the array, `countup(n - 1)` has already been evaluated and returned `[1, 2, ..., n - 1]`.
# --instructions--
We have defined a function called `countdown` with one parameter (`n`). The function should use recursion to return an array containing the integers `n` through `1` based on the `n` parameter. If the function is called with a number less than 1, the function should return an empty array. For example, calling this function with `n = 5` should return the array `[5, 4, 3, 2, 1]`. Your function must use recursion by calling itself and must not use loops of any kind.
# --hints--
`countdown(-1)` should return an empty array.
```js
assert.isEmpty(countdown(-1));
```
`countdown(10)` should return `[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]`
```js
assert.deepStrictEqual(countdown(10), [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]);
```
`countdown(5)` should return `[5, 4, 3, 2, 1]`
```js
assert.deepStrictEqual(countdown(5), [5, 4, 3, 2, 1]);
```
Your code should not rely on any kind of loops (`for`, `while` or higher order functions such as `forEach`, `map`, `filter`, and `reduce`).
```js
assert(
!code.match(/for|while|forEach|map|filter|reduce/g)
);
```
You should use recursion to solve this problem.
```js
assert(
countdown.toString().match(/countdown\s*\(.+\)/)
);
```
Global variables should not be used to cache the array.
```js
countdown(1)
assert.deepStrictEqual(countdown(5), [5, 4, 3, 2, 1]);
```
# --seed--
## --seed-contents--
```js
// Only change code below this line
function countdown(n){
return;
}
// Only change code above this line
```
# --solutions--
```js
function countdown(n){
return n < 1 ? [] : [n].concat(countdown(n - 1));
}
```