I understand that "a" solution is:
function Factorial(number)
{
if(number == 0 || number == 1){
return 1;
}
return number * Factorial(number -1);
}
I want to understand what exactly is going on. I understand what is going on all the way to the last part when number == 1.
If we were to take a simple example of say 3!
3 is not equal to 0 or 1 so we return 3 * Factorial(2)
2 is not equal to 0 or 1 so we return 2 * Factorial(1)
1 is equal to 1 so we return 1
How do we know when to stop? Is it the fact that we return 1 that tells the function to stop?
If that is the case, why does the function not stop when we first return 3 * Factorial(2)? Is it because it's returning a function so that it must continue until it no longer returns a function?
Thank you
I think you have to understand the logic of factorial.
So factorial is just products, indicated by an exclamation mark ie, if you write
0! = 1
1! = 1
2! = 2*1
3! = 3*2*1
4! = 4*3*2*1
5! = 5*4*3*2*1
Hope you find the pattern, so you can write the above factorials as:
0! = 1
1! = 1
2! = 2*1!
3! = 3*2!
4! = 4*3!
5! = 5*4!
So in your function you are using the similar logic.
Now in your function
if(number == 0 || number == 1)
{
return 1;
}
The above logic is to cover the first two cases i.e, 0! and 1! And
return number * Factorial(number -1);
is for the rest of the numbers.
So you are using the recursive technique of solving the factorial problem.
To understand recursion, lets take a number say 5 i.e., we want find the value of 5!.
Then first your function will check
if(number == 0 || number == 1)
which is not satisfied, then it moves to the next line ie,
return number * Factorial(number -1);
which gives
5*Factorial(5-1) which is equal to 5*Factorial(4)
Now on subsequent calls to your Factorial function it will return the value like below:
5*(4*Factorial(4-1)) which is equal to 5*(4*Factorial(3))
5*(4*(3*Factorial(3-1)) which is equal to 5*(4*(3*Factorial(2)))
5*(4*(3*(2*Factorial(2-1)))) which is equal to 5*(4*(3*(2*Factorial(1))))
Now when it returns factorial(1) then your condition
if(number == 0 || number == 1)
is satisfied and hence you get the result as:
5*4*3*2*1 = 120
On a side note:
Beware that factrial is used only for positive integers.
Recursion relies on what is called a base case:
if(number == 0 || number == 1){
return 1;
}
That if statement is called your base case. The base case defines when the recursion should stop. Note how you are returning 1 not returning the result of a call to the function again such as Factorial(number -1)
If the conditions for your base case are not met (i.e. if number is NOT 1 or 0) then you proceed to call the function again with number * Factorial(number - 1)
If that is the case, why does the function not stop when we first return 3 * Factorial(2)?
Your simple example of 3! can be elaborated like this :
return 3 * Factorial(2)
will then be replaced by
return 3 * (2 * Factorial(1))
which then will be replaced by
return 3 * (2 * 1) // = 6 Hence 6 is returned at last and recursion ends.
How do we know when to stop?
When all your Factorial(value) is replaced by a returned value we stop.
Is it the fact that we return 1 that tells the function to stop?
In a way, yes. Because it is the last returned value.
It is called recursion.
This function is called like this
var result = Factorial(3);
in Factorial function
First time
return 3*Factorial(2);
Now here return statement doesnt get executed insted Factorial is called again..
so second time
return 2*Factorial(1);
again in Factorial(1)
Third time
return 1;
So go to second
return 2*1;
Next to first
return 3*(2*1);
Finally
var result = 3*2*1 = 6.
The function is recursing (calling itself) - and taking one from "number" each time.
Eventually (as long as its a positive integer you call it with, otherwise you'll probably get an infinite loop) you'll always hit the condition (number == 1) so instead of recursing further, it'll return 1 rather than call the function again.
Then, once you have hit the bottom (1), it'll start to run the function and work back up the other way along the function call stack, using the previous result each time:
1 = 1
(2*1) = 2
(3*2) = 6
(4*6) = 24
etc
So the final return statement from the function will return the required result
Related
//This program calculates how many times a number is divisible by 2.
//This is the number and the amount of times its been split into 2.
let Num=64
let divisible=0
//This is the ternary operator, it basically asks a question.
Num % 2 === 0 ?
divisible=divisible++ : document.write(divisible);
Num/=2;
Num % 2 === 0 ?
divisible=divisible++ : document.write(divisible);
num/=2
Num % 2 === 0 ?
divisible=divisible++ : document.write(divisible);
//Once the statement evaluates to false it writes the amount of times the number has been divided
by 2 into the document.
You could try it with a loop.
let num=64;
let divisible=0;
while(num % 2 === 0) {
num /= 2;
divisible++;
}
console.log(divisible);
document.write(divisible);
There are several issues with this code. Some of the comments have pointed out the looping concerns. However, one that stands out that won't be addressed with a loop is your misuse of the post-fix increment operator, ++. This operator returns the value and then increments the value, so divisible = divisible++ will result in divisible remaining unchanged. Based on your intent, all you need to do is divisible++.
Try the following:
while(true){
if(Num % 2 === 0){
divisible++;
Num /=2;
}
else{
document.write(divisible);
break;
}
}
Here as per example given for 64 and no looping is provided , it will never go to
document.write(divisible) statement in 3 step provided above . That's why nothing getting printed .
Moreover , divisible=divisible++ doesn't make any sense . Here , since it is postfix operartor , first value will be assigned then it will be incremented so value of divisible will be 0 only .
Num % 2 === 0 ?divisible++ : document.write(divisible);
And , as per my understanding document.write accepts string parameter but here divisible is of number type .
Can anyone explain this to me? I'm having trouble wrapping my head around this concept of having function within a function.
function factorialize(num) {
if (num === 0) {
return 1;
}
return num * factorialize(num-1);
}
factorialize(10);
This is not a loop right? Why does the function call itself continuously? How does it know when to stop? Wouldn't it just continue to factorialize negative numbers to infinity?
Appreciate the help and guidance as always.
This is not a loop right?
Nope, it is not. It is a recursive function, a function that calls itself until a certain condition is met. In this case, is when num is equals to 0.
Why does the function call itself continuously?
Because the function is called in the return value of this function. It will continue calling the function itself, until num equals 0. In which case the function will exit and return 1.
How does it know when to stop?
The condition if (num === 0). The variable num gets subtracted if num isn't equal to 0 as stated in the code return num * factorialize(num-1);. Notice that the function returns fresh function call but with the parameter num - 1. When num becomes 0. The function returns 1.
Wouldn't it just continue to factorialize negative numbers to
infinity?
Because we have this if (num === 0) condition. So the num parameter decreases each time the code return num * factorialize(num-1); gets called, and eventually the above condition gets fulfilled and the function exits.
We can break it down step by step:
factorialize(10) gets called.
num is not 10, so return num * factorialize(num - 1). In this case num is 10 and num - 1 is 9, so we are actually returning the following: 10 * factorialize(10 - 1).
factorialize(9) gets called, then repeat step (1) and (2) until you get factorialize(0).
When you reach factorialize(0), it will return 1. So the whole function effectively returns 10 * 9 * 8 * ... 1 * 1.
Makes sense?
Recursion is a technique for iterating over an operation by having a function call itself repeatedly until it arrives at a result. You can read about it here
Lets visualize:
factorialize(10)
10*factorialize(9)
9*factorialize(8)
8*factorialize(7)
7 *factorialize(6)
6 *factorialize(5)
5 *factorialize(4)
4 *factorialize(3)
3 *factorialize(2)
2 *factorialize(1)
1 *factorialize(0)
1 (if num==0 return 1)
1
2
6
24
120
720
5040
40320
362880
3628800
Hope this helps!
Each time the function "factorialize" runs your argument "num" get decremented by
1. So num will run from 10 to 1 and when 1 is returned it will reach its terminal case 0. It is only terminal because of your "if" clause ( your base case ) when num === 0, you return 1, and your recursive "factorizlize" is never reached, so it is never executed.
I am not really good with analogies. However, If it still doesn't make sense let me know.
Every iterative problem can be solved by using recursion. try to look at this code
var start = 1;
var end = 10;
var increment = 1;
document.write("loop output: ")
for(var num = start; num <= end; num = num + increment){
document.write(num);
document.write(" ");
}
document.write("\n function output:\n")
function iteration(num) {
//stop condition statement
if (num > end) {
return 1;
}
// inside code block
document.write(num);
document.write(" ");
//incremention
iteration(num+increment);
}
iteration(start);
It uses internal functional frame stack for recursion purpose. for more about recursion look here . little practice is need to understand this concept.Hope make sense. Happy Coding !
Here's the relevant function (this example is taken from here):
function factorial (num) {
if (num < 0) {
return -1;
}
else if (num == 0) {
return 1;
}
var tmp = num;
while (num-- > 2) {
tmp = tmp * num;
}
return tmp;
}
console.log(factorial(8));
----> 40320
As I was studying how this function works (and got stumped on the operator precedence in the expression (num-- > 2); kudos to my mentor Edwin Calte at MakerSquare for pointing that out), I noticed that the num variable decrements even though this decrementation is something that is stipulated as a precondition for the loop body to be executed and is not itself part of the loop body. I could understand why it would do that if the expression read instead like:
while (num-- > 2) {
num--;
...}
In the above example, that second num-- isn't necessary for it to work. Another similar expression where this doesn't seem to happen when I run it in my devtools console is:
if (x - 2 == 5) { x-- }
Here, it seems that if x is 7 then x will decrement by 1, not that if x is 7 then 2 will be subtracted from x, and then x will decrement by 1. But in the above example with num, the latter principle is what takes effect.
Could someone please explain why?
Because every time the expression num-- is evaluated (which it is on every iteration of the loop to see if the condition is met) it is decreasing num by one. A lot of JavaScript gurus will tell you to avoid num--, num++, --num, ++num exactly because of their not-so-intuitive side effects.
My advice would be to stick with things that are more readable at first glance, even if it is a few more characters to type.
while (num > 2) {
num = num - 1;
}
At the very least, only use them as standalone statements to make what they are doing clear.
while (num > 2) {
num--;
}
In your second example with the expression x - 2 == 5, this expression does not operate on x at all; it doesn't change it's value. You're not assigning anything back to x like you are when you do x--. x--; is exactly equivalent to x = x - 1;. It just so happens that it also returns the value of x before the assignment is made; this way it can be used as the conditional. It's like reading from a variable and then writing to it all in one statement.
num-- does two things: it subtracts 1 from the variable num (assigning the result back to num) and also returns the original value of the num to be used in the rest of the enumpression. So
(num-- > 2)
is short for:
(temp = num; num = num - 1; temp > 2)
Your while loop could be written as:
while (num > 2) {
num--;
tmp = tmp * num;
}
Notice that I no longer have num-- in the while clause. If I did, the variable would get decremented twice: once while testing the condition, and again inside the loop.
x - 2 would express a new value, ie if you opened the console and typed x - 2 it would respond with 5, but that value is not assigned to anything (and thus x is unaffected). The -- and ++ operators are self-contained statements which affect the variable on which they are operating. So your num-- > 2 is the name as saying num > 2 followed by a num = num - 1, which compares the current value, then performs a mathematical operation and assigns the result of that operation to the variable.
Right now I'm going through Codecademy's recursion track and I'm confused how to interpret this correct code.
// Create an empty array called "stack"
var stack = []
// Here is our recursive function
function power(base, exponent) {
// Base case
if ( exponent === 0 ) {
return 1;
}
// Recursive case
else {
stack[exponent-1] = base * power(base, exponent - 1); //confused by start of this line
return stack[exponent-1];
}
}
power(3,3)
console.log(stack) // [3,9,27]
If exponent-1 becomes 2 then 1 then 0, why does 3 become the element at the 0th position in the array rather than at the 2nd position (and so on) ?
I'd really appreciate any help.
On the first pass, exponent is 3, so you will store a value at stack[2]. But that value is not calculated until the recursive call has completed with power(3,2)...power(3, 1).
So the assignment to stack[3-1] is preceded by the one to stack [3-2], which in turn is preceded by the one to stack[3-2]
Notice that there are four different exponents in the execution of this call, one in each scope of the power invocation.
call power(3, 3)
exponent' = 3
is not 0
calls power(3, 2)
exponent'' = 2
is not 0
calls power(3, 1)
exponent''' = 1
is not 0
calls power(3, 0)
exponent'''' = 0
is 0
returns 1
multiplies the return value by 3
assigns it to stack[exponent'''-1]: stack[0] = 3
returns 3
multiplies the return value by 3
assigns it to stack[exponent''-1]: stack[1] = 9
returns 9
multiplies the return value by 3
asigns it to stack[exponent'-1]: stack[2] = 27
returns 27
logs the value of stack
Indeed the stack is built "backwards", after returning from the recursive calls, not before entering them. If you want to have a better representation of the call stack, you can try to add
callstack.push(exponent);
in the first line of your function body. After the execution of your script, the callstack would look like [3, 2, 1, 0] as you might have expected.
It helps if you write it out in a table:
power(3, 3) stack[2] = 3 * power(3, 2)
power(3, 2) stack[1] = 3 * power(3, 1)
power(3, 1) stack[0] = 3 * power(3, 0)
power(3, 0) return 1
Then substitute the values:
stack[0] = 3 * 1
stack[1] = 3 * 3
stack[2] = 3 * 9
I can't figure out how this recursive call works. Using the not operator in the recursive call somehow makes this function determine if the argument given is odd or even. When the '!' is left out fn(2) and fn(5) both return true.
This example is taken out of JavaScript Allonge free e-book, which, so far has been excellent.
var fn = function even(n) {
if (n === 0) {
return true;
}
else return !even(n - 1);
}
fn(2); //=> true
fn(5); //=> false
If n === 0 the result is true.
If n > 0 it returns the inverse of n - 1.
If n === 1 it will return !even(0), or false.
If n === 2 it will return !even(1), or !!even(0), or true.
If n === 3 it will return !even(2), or !!even(1), or !!!even(0), or false.
And so on...
In general:
If n is even, the result is inverted an even number number of times, meaning it will return true.
If n is odd, the result is inverted an odd number number of times, meaning it will return false.
The above function reurns recursively the negation of it self.The base-case is when the number provided becomes zero and each time the function calls it self the number is decreased by one. As a result we have n recursive negations starting with true at base-case (where n is the number provided). For an odd number of negations given true as a starting value you get false as the result and for an even number you get true.
In summary:
Starting from given n
recursive reduction of n
Basecase: n=0 returns true
recursive negation of returned value(starting from true at base-case)
Result:
for odd number of negations the value returned is false
for even number of negations the value returned is true
Lets say we have example n=5
recursive reduction of n. Values of n at each level:
5
4
3
2
1
0 (base-case)
returned values at each level:
true (base case)
!true
!!true
!!!true
!!!!true
!!!!!true
A variant of you code could be:
function even(n) {
if (n === 0)
return true;
else
return odd(n - 1);
}
function odd(n) {
if (n === 1)
return true;
else
return even(n - 1);
}
We know that all positive numbers starting from 0 alternating between being even and odd. What you example does is defining odd to be !even which is correct since odd/even are disjoint. In your version using !, the not needs to be done as a continuation. That means every instance need to do something with the answer after the recursive call returns.