freeCodeCamp Challenge Guide: Factorialize a Number

freeCodeCamp Challenge Guide: Factorialize a Number
0

Factorialize a Number


Hints

Hint 1

You know your solution should return 1 when the number passed to the function is 0 or 1. Also, the final value returned will be the product of all the numbers between 1 and the number (inclusive). If you initialize the value for the product to 1, then think how you could start at the given number and continue decrementing this number until a specific value while multiplying the product by the number at each step.

Recursive Solution

This one starts easily since 0! = 1, so you can go ahead and simply return 1 there.

We can use that as an if in order to break the loop we’re going to create using a recursive function. It will check if the number you gave the function is 0 (which would be the end of your factorial chain). Functions “end” when they return anything. In fact, all functions without an explicit return statement will return undefined.

This is also why instead of having “finished”, a function is always said to “have returned”. And now this…

Understanding recursion

Recursion refers to a function repeating (calling) itself. In this case we are basically returning the given number (i.e. 5), multiplied by the function itself but this time the value passed to the num parameter is num-1 (which initially translates to 4). The very function is going to run inside itself interesting, eh?

Understanding the flow

The first returned value can be visualized better if you think about those parenthesis operations you did in secondary school where you do the math inside every parenthesis from inside out, bracket and square bracket until you get a final result (a total). This time it’s the same thing, look at the program flow:

During the first execution of the function:

[num = 5]

Is 5 equal to 1 or 0? No —> Oki doki, let’s continue…

Returns:

(5 _(second execution: 4 _(third execution: 3 _(fourth execution: 2 _fifth execution: 1))))

What it returns can be viewed as (5*(4*(3*(2*1)))) or just 5 * 4 * 3 * 2 * 1, and the function will return the result of that operation: 120. Now, let’s check what the rest of the executions do:

During the rest of the executions:

Second Execution: num = 5-1 = 4 -> is num 0 or 1? No

–> return the multiplication between 4 and the next result when num is now 4-1.

Third Execution: num = 4 - 1 = 3 -> is num 0 or 1? No

–> return the multiplication between 3 and the next result when num is now 3-1.

Fourth Execution: num = 3-1 = 2 -> is num 0 or 1? No

–> return the multiplication between 2 and the next result when num is now 2-1.

Fifth Execution: num = 2-1 = 1 -> is num 0 or 1? Yep

–> return 1. And this is where the recursion stops because there are no more executions.

Relevant Links


Solutions

Solution 1 (Click to Show/Hide)
function factorialize(num) {
  for (var product = 1; num > 0; num--) {
    product *= num;
  }
  return product;
}

factorialize(5);

Code Explanation

  • Since the return values for the function will always be greater than or equal to 1, product is initialized at one. For the case where the number is 0, the for loop condition will be false, but since product is initialized as 1, it will have the correct value when the return statement is executed.

  • For all numbers passed to the function which are greater than one, the simple for loop will decrement num by one each iteration and recalculate product down to the value 1.

Solution 2 (Click to Show/Hide) (using Recursion)
function factorialize(num) {
  if (num === 0) {
    return 1;
  }
  return num * factorialize(num - 1);
}

factorialize(5);

Code Explanation

Notice at the first line we have the terminal condition, i.e a condition to check the end of the recursion. If num == 0, then we return 1, i.e. effectively ending the recursion and informing the stack to propagate this value to the upper levels. If we do not have this condition, the recursion would go on until the stack space gets consumed, thereby resulting in a Stack Overflow.

Relevant Links

Solution 3 (Click to Show/Hide)
function factorialize(num, factorial = 1) {
  if (num == 0) {
    return factorial;
  } else {
    return factorialize(num - 1, factorial * num);
  }
}

factorialize(5);

Code Explanation

  • In this solution, we use Tail Recursion to optimize the the memory use.

  • In traditional head recursion, the typical model is that you perform your recursive calls first, and then you take the return value of the recursive call and calculate the result. In this manner, you don’t get the result of your calculation until you have returned from every recursive call.

  • In tail recursion, you perform your calculations first, and then you execute the recursive call, passing the results of your current step to the next recursive step. This results in the last statement being in the form of (return (recursive-function params)).

  • In this solution, with each evaluation of the recursive call, the factorial is updated. This is different from the head-recursive solution where all evaluation calculations are stored on the stack until the base case is reached.

Relevant Links

Solution 4 (Click to Show/Hide)
function factorialize(num, factorial = 1) {
  return num < 0 ? 1 : (
    new Array(num)
      .fill(undefined)
      .reduce((product, val, index) => product * (index + 1), 1)
  );
}
factorialize(5);

Code Explanation

  • In this solution, we used “reduce” function to find the factorial value of the number.
  • We have created an array which has length num. And we filled all elements of the array as undefined. In this case, we have to do this because empty arrays couldn’t reducible. You can fill the array as your wish by the way. This depends on your engineering sight completely.
  • In reduce function’s accumulator is calling product this is also our final value. We are multiplying our index value with the product to find factorial value.
  • We’re setting product’s initial value to 1 because if it was zero products gets zero always.
  • Also the factorial value can’t calculate for negative numbers, first of all, we’re testing this.
14 Likes

The solution code doesn’t appear to work…?
Maybe I’m missing something but I tried it as above and did not work.

It works fine for me. Check this.

1 Like

who does the credit for the solution of this go too

pls is factorialize a real function in javascript? or can a function of itself be declared inside it self, is dat possible

2 Likes

It’s a function you define yourself. Checkout “Recursion” under the Relevant Links section above:

Recursion

1 Like

Just wondering the pros and cons of these two solutions and which if either is better and why.

I came up with this solution.

function factorialize(num) {
  var factode = 1;
  for(var i = num; i > 0; i--) {
    factode *= i;
    
  }
  return factode;
}
  

factorialize(5);

but the wiki provides this solution…

function factorialize(num) {
  if (num === 0) { return 1; }
  return num * factorialize(num-1);
}

factorialize(5);
8 Likes

Here are my two versions (iterative and recursive). The solution code at the top for this challenge does not cover the case where num is negative such as in factorialize(-2). My solutions return undefined for this edge case.

// iterative version
function factorialize(num) {
  if (num < 0) return;
  for (var product=1; num > 0; num--) product *= num;
  return product;
}

// recursive version
function factorialize(num) {
  return num < 0 ? undefined : num <= 1 ? 1 : num * factorialize(num - 1);
}
6 Likes

exactly i did it the way we were taught when we were kids in basic level languages so i did the first way u commented and it worked.

This was my solution too! Clearly the wiki solution is more elegant, but I would also be interested in an explanation of the pros and cons.

var fact=1;

function factorialize(num) {
for(var i=num;i>0;i–){
fact=fact*i;
}
return fact;
}

factorialize(10);
can u tell me why can’t I declare the var fact globally…?

1 Like

var fact=1
function factorialize(num) {
for(var i=num;i>0;i–){
fact=fact*i;
}
return fact;
}

factorialize(10);

what is the problem in declaring var fact=1 globally instead of locally?

My solution

function factorialize(num) {
  var fat = 1;
  if(num===0){
    fat = 1;
  } else {
    for(i=2;i<num+1;i++){
       fat = fat * i;
    }
  }
  return fat;
}

factorialize(10);
3 Likes

Here is my solution. It passed the tests, but wanted to see if this solution would cause issues. Right off the bat, i see that it cannot process Negative numbers.

I defined factor and set it equal to 1. if 0 or lower, my program spits out 1. it did pass the test though.

function factorialize(num) {
var factor = 1;
for (var x = 1; x <= num; x++) {
factor *= x;
}
return factor;
}

factorialize(5);

How could I change this to also include negative numbers?

2 Likes

One thing is you want your function to be reusable and to do the same thing every time it’s called. If you declare fact globally, you never ‘reset’ it to 1 when you run the function a second time or a third. Essentially, you’re changing the value of fact every time the factorialize(x) is run.

1 Like

Because then the value of your fact variable will be changed each time you run your factorialize() function, it won’t reset back to 1 when you’re done.

Example:
factorialize(3); //returns fact as 1321=6 since it’s the first time you used it.
factorialize(4);//returns fact as 6
432*1=144 instead of 24 because you changed your global variable fact’s value from 1 to 6 when you ran factorialize(3).

What’s wrong with this code, please?

function factorialize(num) {
var fact = 1;
for (var i = num; i <= num ;i–){
fact = fact * i ;
}
return fact;
}

This one is a basic for loop with a special condition if factorial is 0



function factorialize(num) {
  for (var i=num-1; i>0; i--){
    num*=(i);
  }
  if (num ==0){
    num = 1;
  }
  return num;
}

factorialize(5);

This is one liner version answer using a ternary operator and recursion

function factorialize(num) {
  return num===0 ? 1 : num*factorialize(num-1);
}

factorialize(5);
6 Likes