making a factorial in javascript with recursion beginner - javascript

function nFactorial(n) {
// return the factorial for n
// example:
// the factorial of 3 is 6 (3 * 2 * 1)
if (n < 0){
return;
}
if (sum === undefined){
sum = 1;
}
sum *= n;
nFactorial(n - 1);
return sum;
}
nFactorial(3);
I'm doing my first stab at learning recursion in javascript. I'm trying to solve a problem where I'm making a factorial. I error I get right now is
ReferenceError: sum is not defined
Can anyone point me in the right direction? I'm feeling a little lost.

For using a product as return value, you could use tail call optimization of the recursion by using another parameter for the product (which replaces the sum in the question).
function nFactorial(n, product) {
product = product || 1; // default value
if (n < 0) { // exit condition without value
return;
}
if (n === 0) { // exit condition with result
return product;
}
return nFactorial(n - 1, n * product); // call recursion at the end of function
}
console.log(nFactorial(3));
This approach minimizes the stack length, because the last call does not extend the stack, as opposite of the standard approach of the following recursion without a product parameter.
function nFactorial(n) {
if (n < 0) {
return;
}
if (n === 0) {
return 1;
}
return n * nFactorial(n - 1);
}
console.log(nFactorial(3));

the way you write your code will result always in 0 , here is the correct way for a factorial with recursion, also you need to check if n is a number or the code will trow an error
const factorial =(n)=> {
if(isNaN(n)){
console.log("enter a number")
return 0
}
if(n === 0) {
return 1
} else {
return n * factorial(n - 1);
}
}
console.log(factorial(5));

A simple implementation:
function factorial(n) {
if (n === 1 || n === 0) {
return n;
}
return n * factorial(n-1);
}

Related

Is finding the factorial of 5000 possible in javascript

I want to find the factorial of 5000 but once I try to pass 100 it'll return infinity. Is there are way to bypass this and get the result? I am trying to get the time it takes to solve this.
function testSpeed(n) {
if (n > 0 && n <= 1) {
return 1;
} else {
return n * testSpeed(n-1);
}
}
console.log(testSpeed(5000));
As you've noticed, Javascript numbers can only get so big before they just become "Infinity". If you want to support bigger numbers, you'll have to use BigInt.
Examples:
// Without BigInt
console.log(100 ** 1000) // Infinity
// With BigInt
// (stackOverflow doesn't seem to print the result,
// unless I turn it into a string first)
console.log(String(100n ** 1000n)) // A really big number
So, for your specific bit of code, all you need to do is turn your numeric literals into BigInt literals, like this:
function testSpeed(n) {
if (n > 0n && n <= 1n) {
return 1n;
} else {
return n * testSpeed(n-1n);
}
}
console.log(String(testSpeed(5000n)));
You'll find that youe computer can run that piece of code in a snap.
This seems to give the correct result (according to https://coolconversion.com/math/factorial/What-is-the-factorial-of_5000_%3F)
const longFactorial = (num) => {
let result = num;
for (let i = 1n; i < num; i++) {
result = result * (num - i)
}
return String(result);
}
console.log(longFactorial(5000n));
I can receive for 170! maximum:
function factorial (y){
if (y ==0 || y ==1){
return 1;
}
else {
f = y - 1;
while (f >= 1) {
y = y * f;
f--;
}
return y;
}
}
console.log(factorial(170));

Why is my factorial function returning NaN?

I wrote a factorial function using recursion and a while-loop but it's return value is NaN whenever it is called. Please I want to know why? and how to fix it?
Function
function factorial(n) {
while(n > 0)
return factorial(n - 1) * n;
}
You're missing the return statement for the base case. The function returns undefined when you return without a value, and when you multiply that you get NaN.
Also, you're not looping, so you should use if rather than while.
function factorial(n) {
if (n > 0) {
return factorial(n - 1) * n;
} else {
return 1;
}
}
console.log(factorial(10));
You can also write it with looping instead of recursion.
function factorial(n) {
result = 1;
for (var i = 1; i <= n; i++) {
result *= i;
}
return result;
}
console.log(factorial(10));
If you track your recursion, you'll see when n reaches 1, which make n-1 = 0 and the factorial(0) is called, your function does not know what to do next and does not return any number (NaN). That NaN multiplies with all other things returning another NaN.
Add an instruction for your function in to handle n = 0:
function factorial(n) {
if (n == 0) return 1;
while(n > 0)
return factorial(n - 1) * n;
}
Just add the base case n === 0 to n === 1 to end the tail recursion.
console.log(function factorial(n) {
if (n === 0 || n === 1) {
return 1;
}
return factorial(n - 1) * n;
}(4));
you can also write it in single line:
const factorial = (n) => (n > 1) ? factorial(n-1) * n : 1

powerofTwo algorithm solution

Below is my algo to check if number is a power of two. When I run this algo in test case "2" the answer is false. I want to know why it behaves this way ?
var isPowerOfTwo = function(n) {
if(n === 1){
console.log("i came here");
return true;
}
if(n === 0){
return false;
}
if(n%2 === 0){
console.log(n);
n=n/2;
console.log(n);
isPowerOfTwo(n);
}
if(n%2 === 1){
return false;
}
};
You're not returning the recursive call, and you're also changing n before the tests have finished - if n / 2 resolves to 1 then your reassignment of n will result in the bottom if statement running. Use else instead, and don't reassign n, simply pass n / 2 to the recursive call:
var isPowerOfTwo = function(n) {
if (n === 1) return true;
if (n === 0) return false;
if (n % 2 === 0) return isPowerOfTwo(n / 2);
else return false;
};
console.log(isPowerOfTwo(2));
console.log(isPowerOfTwo(8));
console.log(isPowerOfTwo(6));
Your if (n%2 === 1) return false; condition could result in another bug: what if the initial n was not an integer? Then the function would call itself forever, resulting in an overflow.
Because 1 % 2 === 1
The "problem" is that in the third if you are changing the value of n and not returning any value so it will enter the last if too.
As mentioned, you don't return any value in the 3rd if statement, hence you always get false for values greater than 1 as it will execute the 4th statement too.
In addition to the given answers, here is an interesting solution (initially by Jaromanda X), which I expanded so it deals with if a non-number is passed as a value.
Try cast to a number
const isPowerOfTwo = n => Number(n).toString(2).split('1').length === 2
console.log(isPowerOfTwo(''));
console.log(isPowerOfTwo('0'));
console.log(isPowerOfTwo('1'));
console.log(isPowerOfTwo('2'));
console.log(isPowerOfTwo(2));
console.log(isPowerOfTwo(8));
console.log(isPowerOfTwo(6));
Check the type
const isPowerOfTwo = n => typeof n === 'number' && n.toString(2).split('1').length === 2
console.log(isPowerOfTwo(''));
console.log(isPowerOfTwo('0'));
console.log(isPowerOfTwo('1'));
console.log(isPowerOfTwo('2'));
console.log(isPowerOfTwo(2));
console.log(isPowerOfTwo(8));
console.log(isPowerOfTwo(6));
I think you just need to return an actual value from the n % 2 === 0 branch of your function:
var isPowerOfTwo = function(n) {
if (n === 1) {
console.log("i came here");
return true;
}
else if (n === 0) {
return false;
}
else if (n % 2 === 0) {
console.log(n);
n = n / 2;
console.log(n);
return isPowerOfTwo(n);
}
else { // no need for an if here
return false;
}
};
Note that in the final else we do not need to check anything, because we have already ascertained the number is not a multiple of 2.
Javascript one-liner solution
For any power of 2 (n & n - 1) will return 0. Simple bit-wise operators
isPowerOfTwo = n => !(n & n - 1)
The above function will return true for 0, which is not a power of 2. For that
isPowerOfTwo = n => (n != 0) && !(n & n - 1)

Sum of even numbers from 1-100 using recursive function in Javascript

I want to sum even numbers from 1-100 using javascript recursive function, but the output just show me 0 for odd numbers and the number itself for odd numbers
function evenSum(n) {
if (n%2 === 1) {
return 0;
}
else if (n === 100) {
return 100;
}
return n + evenSum(n+1);
}
if (n%2 === 1) {
return 0;
}
That will stop the recursive chain at every second number. For every odd number it will stop directly (and return 0) for every even number it will stop at the second position. Instead, you just want the recursion to continue with the next chain:
if (n%2 === 1) {
return evenSum(n + 1);
}
Actually you can simplify (and speed up the code) if you just go to every second position:
function evenSum(n){
// Stop at 100
if(n >= 100) return 100;
// If it starts at an odd position, go on with the next even
if(n % 2 === 1) return evenSum(n + 1);
// Usually just take every second step:
return n + evenSum(n + 2);
}
That can be shortified to:
const evenSum = n => n >= 100 ? 100 : n % 2 ? evenSum(n + 1) : n + evenSum(n + 2);
You could use a recursion function which count down the values until you reach zero.
The exit condition is a check if the number is smaller or equal to zero, then return the sum otherwise decrement uneven value by one and even value by two and call the function again with the value and temporary sum.
function evenSum(n, s = 0) {
if (n <= 0) {
return s;
}
return evenSum(n - (n % 2 ? 1 : 2), s + n); // tail recursion
}
console.log(evenSum(100));
function evenSum(n) {
if (n <= 1)
return 0;
else
{
if(n%2 === 1)
return evenSum(n - 1);
else
return n + evenSum(n - 1);
}
}
Something like that (works for all numbers, not just 100):
function evenSum(n) {
if (n == 0) return 0; // recursive function needs to stop somewhere
var sum = evenSum(n - 1); // recursive call
if (n % 2 == 0) sum += n; // add current n if it's even
return sum; // return result
}
console.log(evenSum(100));
recursive sum of even number
one line condition
function addOddToN(n) {
return (n <= 2) ? 2 : (n%2 === 0) ? n + addOddToN(n - 1) : addOddToN(n - 1);
}
console.log( addOddToN(100) ); // 2550
console.log( addOddToN(5) ); // 6
console.log( addOddToN(4) ); // 6
console.log( addOddToN(10) ); // 30

JavaScript: Too much recursion?

I am learning JavaScript through Eloquent JavaScript and one of the exercises is to write a recursive function, isEven, that returns true if a number is even or false if a number is odd.
If I understood correctly, the author specifically wanted the following to be implemented:
If a number == 0, then it is even.
If a number == 1, then it is odd.
"For any number N, its evenness is the same as N-2".
But when I use the code I have below, I get an error: InternalError: too much recursion (line 3 in function isEven) … How can I fix this while still using a recursive function?
// Your code here.
function isEven(n){
if(n==0){
return true;
}
else if(n==1){
return false;
}
else{
n = n-2;
isEven(n);
}
}
console.log(isEven(50));
// → true
console.log(isEven(75));
// → false
console.log(isEven(-1));
// → ??
You could add another check, before decrementing/incrementing a value.
function isEven(n) {
if (n == 0) {
return true;
}
if (n == 1) {
return false;
}
if (n > 0) {
n = n - 2;
} else {
n = n + 2;
}
return isEven(n);
}
console.log(isEven(50));
console.log(isEven(75));
console.log(isEven(-1));
To handle it recursion with that function, the value needs to be its absolute value.
console.log("isEven");
function isEven(n) {
//Ensure that we look at the numbers absolute value
n = Math.abs(n);
//Do a loop instead of recursion
if (n == 0) {
return true;
} else if (n == 1) {
return false;
} else {
n = n - 2;
return isEven(n);
}
}
console.log(isEven(50));
console.log(isEven(75));
console.log(isEven(-1));
console.log("fasterIsEven");
//A faster way that eliminates recursion
function fasterIsEven(n) {
return n % 2 === 0;
}
console.log(fasterIsEven(50));
console.log(fasterIsEven(75));
console.log(fasterIsEven(-1));
Javascript has a build-in method to test if something is dividable with something else, called modulus (%). This method is faster, but not recursive.
function IsEven(n){ return n%2 === 0 }
The core code is this one
return n%2 === 0
In order to increase the program's strength, it is recommended to increase non-number decisions.

Categories

Resources