what is wrong with my recursion code? - javascript

I have a recurrence series so i have converted into recursion form.
But it will show as maximum stack size reached.
The same code is working with n=4 as fn(4) and working correctly but not working with higher values. what is the problem with higher values such as n = Math.pow(10, 18)
var fn = function(n){
// take initial value of f(0) = 1 & f(1) = 1
if(n===1 || n=== 0) return 1;
//calculate on basis of initial values
else if (n === -1) return (fn(1) - 3* fn(0) - gn(-1) - 2* gn(0));
else
return (3*fn(n-1) + 2 * fn(n-2) + 2* gn(n-1) + 3* gn(n-2));
};
var gn = function(n){
// take initial value of g(0) = 1 & g(1) = 1
if (n === 1 || n === 0) return 1;
//calculate on basis of initial values
else if(n === -1) return ((gn(1) - gn(0)) / 2);
else return (gn(n-1) + 2* gn(n-2));
};

The problem with higher values, such as n = Math.pow(10, 18) is that the stack is simply not that big. (Not even close.) You can usually have a stack depth of a couple thousand, and not much more.
You should use iteration instead.

Related

Recursion is 4 but the expected output is 64

let power2 = (x,n) => {
if(n == 0) return 1;
let temp = power2(x,n/2);
if(n%2 == 1) return temp * temp * x;
return temp*temp;
}
console.log(power2(4,3));
This method has less nodes and time complexity but its giving wrong output
The problem with the original code was the fact that n / 2 will result in a real number when you need it to be treated as an integer. Bitwise operation are always performed on integers so n >> 1 will correctly yield an integer. The same goes with modulo which converts the number to an integer first that's why it worked correctly in your code.
let power2 = (x, n) => {
if (n === 0) return 1;
const temp = power2(x, (n >> 1));
if (n % 2 === 1) return temp * temp * x;
return temp * temp;
}
console.log(power2(4, 3));
If you need custom integer power function, based on recursion, consider this snippet:
// Custom pow
const myPow = (n, i) => i > 0 ? myPow(n, i - 1) * n : 1;
// Test
console.log(myPow(4, 3));

codewars kata: "Is my friend cheating?" Passed all test but using bruteforce, If someone could help me optimize my code by using actual math maybe?

Here is my solution
export function removeNb (n:number):number[][] {
const total = n * (n+1) / 2;
for(let a = n; a > 1; a--){
for(let b = a-1 ;b > 1 ; b--){
if(total - b - a === b*a){
return [[b,a],[a,b]]
}
}
}
return []
}
The problem is this:
A friend of mine takes the sequence of all numbers from 1 to n (where
n > 0).
Within that sequence, he chooses two numbers, a and b.
He says that the product of a and b should be equal to the sum of all
numbers in the sequence, excluding a and b.
Given a number n, could you tell me the numbers he excluded from the
sequence?
The function takes the parameter: n (n is always strictly greater than
0) and returns an array of arrays.
The test cases are as follows:
removeNb(26); //[[15,21],[21,15]]
removeNb(101); //[[55,91],[91,55]]
removeNb(102); //[[70,73],[73,70]]
removeNb(110); //[[70,85],[85,70]]
Update
As Ike mentioned the previous solution doesn't take in account the fact that a and b both need to be less or equal to n so the solution should be updated like this : (b needs to be less then n, ie (total - a) / (a + 1) <= n ie (total - n) / (n + 1) <= a)
function removeNb(n: number) {
const total = n * (n + 1) / 2;
const t: [number, number][] = [];
for (let a = Math.ceil((total - n) / (n + 1)); a * a < total; a++) {
const b = (total - a) / (a + 1)
if (!(b % 1)) t.push([a,b],...(a === b ? [] : [[b,a]]))
}
return t
}
With a bit of maths we can check that tatal - a - b = a * b is equivalent to (total - a) / (a + 1) = b so we can deduce b from a and just check if it is an integer.
Also since a and b are exchangeable we can require b to be greater or equal a i.e (total - a) / (a + 1) >= a <=> total >= a * (a + 2) so we can require a² < total.
So your function can be optimized this way:
function removeNb(n: number) {
const total = n * (n + 1) / 2;
const t: [number, number][] = [];
for (let a = 1; a * a < total; a++) {
const b = (total - a) / (a + 1)
if (!(b % 1)) t.push([a,b],...(a === b ? [] : [[b,a]]))
}
return t
}

Determine a prime number function

Could anyone explain to me the 2nd and 3rd statement in the for loop
What is the 1st and 2nd i in the middle part and the last one (i = i + 6)
function prime(n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false
for (let i = 5; i * i <= n; i = i + 6) {
if (n % i == 0 || n % (i + 2) == 0)
return false;
}
return true
}
console.log(prime(11))
console.log(prime(25))
console.log(prime(29))
There are a couple of hacks in this function to determine primality of a number n.
Every non-prime number has at-least 1 factor less than or equal to its square root.
Every 6th number from 3 onwards is a multiple of 3. So, if we have already checked that 3 does not divide n, we can safely say numbers like 9,15,21... will not divide n.
The if inside the loop checks for divisibility of n by i or i + 2. Since we know, 3 | i+4 (-- from 2 above), we don't check divisibility there as it is not required. And since this loop runs from i = 5 upto i = sqrt(n), if we find no factors, we can exit the loop and return true for number's primality (-- from 1 above)

RangeError: Maximum call stack size exceeded with recursion

I am trying to solve this kata on Codewars: https://www.codewars.com/kata/56e56756404bb1c950000992/train/javascript, and I have a method that I think should be correct, but it throws a RangeError. This is my code:
function sumDifferencesBetweenProductsAndLCMs(pairs){
return pairs.reduce((acc, curr) => {
// LCM * GCD = product
return acc + (curr[0] * curr[1] * (1 - 1 / GCD(curr)))
}, 0)
}
function GCD(pair) {
// Euclidean algorithm
let a = Math.max(...pair);
let b = Math.min(...pair);
let r = a % b;
if (r == 0) {
return b;
}
return GCD([b, r]);
}
Where am I going wrong? How else can I implement the Euclidean Algorithm?
I'm not sure I get any of the maths stuff here, but skipping zeros seems to stop it from trying to recurse forever.
Anything % 0 will give NaN and probably anything % NaN will give NaN and NaN == 0 is false, so if you start with a zero value entering GCD there's no way for the recursion to terminate.
function sumDifferencesBetweenProductsAndLCMs(pairs){
return pairs.reduce((acc, curr) => {
// LCM * GCD = product
if(Math.min(...curr) === 0) return acc; // Skip zeros
return acc + (curr[0] * curr[1] * (1 - 1 / GCD(curr)))
}, 0)
}
function GCD(pair) {
// Euclidean algorithm
let a = Math.max(...pair);
let b = Math.min(...pair);
let r = a % b;
if (r == 0) {
return b;
}
return GCD([b, r]);
}
console.log(sumDifferencesBetweenProductsAndLCMs([[15,18], [4,5], [12,60]]),840);
console.log(sumDifferencesBetweenProductsAndLCMs([[1,1], [0,0], [13,91]]),1092);
console.log(sumDifferencesBetweenProductsAndLCMs([[15,7], [4,5], [19,60]]),0);
console.log(sumDifferencesBetweenProductsAndLCMs([[20,50], [10,10], [50,20]]),1890);
console.log(sumDifferencesBetweenProductsAndLCMs([]),0);

Problem in delimiting a limit for a loop. Euler problem 5

I have a question, my code worked but in the case that it's a bigger number and I don't have an idea of where to put the limit in my i position... How can I optimize this code, so I don't need to calculate the limit and not put so many zeros in my i? Or there's no way and this is as it should be?
function prob5(){
for(var i =1;i<10000000000;i++){
if((i%1)==0 && (i%2)==0 && (i%3)==0 && (i%4)==0 && (i%5)==0 && (i%6)==0 && (i%7)==0 && (i%8)==0 && (i%9)==0 && (i%10)==0 && (i%11)==0 && (i%12)==0 && (i%13)==0 && (i%14)==0 && (i%15)==0 && (i%16)==0 && (i%17)==0 && (i%18)==0 && (i%19)==0 && (i%20)==0) {
break;
}
}
console.log(i);
}
function getLowestNumDivisibleByAllUpTo(limit) {
const numMax = factorial(limit);
for (let num = 1; num < numMax; num++) {
let divisibleByAll = true;
for (let divisor = 2; divisor <= limit; divisor++) {
if (num % divisor !== 0) {
divisibleByAll = false;
break;
}
}
if (divisibleByAll) {
return num;
}
}
}
function factorial(n) {
if (n < 2) return 1;
return n * factorial(n - 1);
}
console.log(getLowestNumDivisibleByAllUpTo(20));
/*
the number you are looking for is called the least common multiple (lcm)
to find the least common multiple of all numbers in an array:
compute the lcm of the first two, then the lcm of the fist two with the third and so on
lcm(2,3)=6, lcm(6,4)=12, lcm(12,5)=60, etc
the following is much more efficient because it doesn't search billions of numbers
to check if they are divisible by 2 and 3 and 4 and ... 20
it just applies the same function, lcm, 18 times
*/
const limit = 20;
const divisors = [...Array(limit - 1)].map((v, i) => 2 + i);
// greatest common divisor of two numbers
const gcd = (a, b) => b ? gcd(b, a % b) : Math.abs(a);
// least common multiple of two numbers
const lcm = (a, b) => a * b / gcd(a, b);
// least common multiple of all numbers in an array
const lcma = array => array.reduce(lcm);
console.log(lcma(divisors));

Categories