This question already has answers here:
JavaScript Fibonacci breakdown
(3 answers)
Closed 3 years ago.
I tried playing around with recursion in javascript. I wrote a function for the Fibonacci sequence. However, if only works if the argument is 0
fib = (x)=>{
if (x == 0 || x ==1) {
return 1
} else {
return fib(x-1) + fib(x+1)
}
}
It returns 1 for 1, but a number above 0 I get the error maximum call stack size exceeded
This is not the Fibonacci sequence. This is the Fibonacci sequence:
fib = (x) => {
if (x == 0 || x == 1) {
return 1;
} else {
return fib(x - 1) + fib(x - 2);
}
}
for (let i = 0; i < 10; i++) {
console.log(fib(i));
}
In its simplest form, of course. If you go too far beyond 10, you'll experience what an exponential cost of computation can do to a computer.
You need the value of the second last iteration, no an iteration ahead.
Please have a look here, too: Fibonacci number.
const fib = x => {
if (x === 0 || x === 1) {
return 1;
}
return fib(x - 2) + fib(x - 1);
};
console.log(fib(7));
Related
Here is the question.
Find the greatest common divisor of two positive integers. The integers can be large, so you need to find a clever solution.
The inputs x and y are always greater or equal to 1, so the greatest common divisor will always be an integer that is also greater or equal to 1.
Here is my solution.
function mygcd(x, y) {
//your code here
let gcd = [];
let lowestNum;
let bigestNum;
//detect the lowest and bigest numbers
if (x < y) {
lowestNum = x;
bigestNum = y;
} else if (x > y) {
lowestNum = y
bigestNum = x;
} else {
lowestNum = x
}
//check if the bigest num has a modolo == 0
//else loop the lowest num and push in the array
if (bigestNum % lowestNum === 0) {
return gcd += lowestNum;
} else {
let arrNum = []
for (let i = 1; i < lowestNum; i++) {
// console.log(i)
arrNum.push(i)
}
//loop the array backwards
for (i = arrNum.length - 1; i >= 1; i--) {
if (lowestNum % arrNum[i] === 0 && bigestNum % arrNum[i] === 0) {
console.log(arrNum[i])
if (gcd !== 0) {
return
} else {
// gcd += arrNum[i]
let vals = gcd.push(arrNum[i])
console.log(typeof(vals))
}
}
}
}
console.log(gcd)
return gcd[0];
}
console.log(mygcd(30, 12))
The above solution works for the test cases i tried it for, but the issue is that it returns the correct divisor and undefined.
This is what my logs look like
6
undefined
6
undefined
The test cases
test:
Log
6
expected undefined to equal 6
so it gets undefined instead of 6 or the correct divisor.
I also tired a different recursive approach below.
Note: This works well.
function mygcd(x, y) {
if (!x) return y
if (!y) return x
return mygcd(y, x % y)
}
console.log(mygcd(30, 12))
console.log(mygcd(8, 12))
But i am curious to understand why my original solution breaks. Any help would be really appreciated.
Thanks
This question already has answers here:
Recursive function returns undefined
(3 answers)
Closed 1 year ago.
Please, help me. I don't understand. Why second solution returns undefined?
function digital_root(n) {
return n < 10 ? n : digital_root(n.toString().split('').map(Number).reduce((a, b) => a + b));
}
console.log(digital_root(12345678));
// expected output: 9
function digital_root(n) {
if (n < 10) {
return n;
} else {
digital_root(n.toString().split('').map(Number).reduce((a, b) => a + b));
}
}
console.log(digital_root(12345678));
// output: undefined
This happens because your second code ignores the value you get returned from the recursive call. You should do something with it... return it.
function digital_root(n) {
if (n < 10) {
return n;
} else {
return digital_root(n.toString().split('').map(Number).reduce((a, b) => a + b));
}
}
console.log(digital_root(12345678));
Unrelated, but you can combine split and map by doing Array.from. Also the first version joins the two return statements with the conditional operator into a return of one expression:
const digital_root = n => n < 10 ? n
: digital_root(Array.from(n.toString(), Number).reduce((a, b) => a + b));
console.log(digital_root(12345678));
I am solving this problem on hackerrank. It seems to be a simple problem where I count all the value that are <= 0 in the array and return whether the count equals to k, which is what I have implemented in my code. I pass the test case just fine but fail all other 11 hidden cases. What am I doing wrong?
function angryProfessor(k, a) {
let count = 0;
for (let num of a) {
if (num <= 0) {
count++;
}
}
if (count === k) {
return 'NO'
} else {
return 'YES'
}
}
The question asks a minimum number of students, for e.g. if k=3 then if there are more than 3 students then also the class will happen.So change your if condition i.e. if (count === k) condition to this if (count >= k)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have a variable var num = 12;
And I want to add both integers (1 and 2) in the num to equal 3 in JavaScript. I'm doing this to an array of elements that has two digit numbers.
Can someone solve this? I have tried and I need help.
You could turn the number into an array of strings then use the map and reduce function to change them to numbers and add them together like so:
let num = 12;
let sum = [...`${num}`].map(Number).reduce((a, b) => a + b);
or [...`${num}`].reduce((a, b) => +a + +b);
Does this help?
num.toString().split('').reduce((a,b) => parseInt(a)+parseInt(b),0)
String(12).split("").reduce((sum, d)=> sum += parseInt(d),0);
Works for any number.
Here is a solution, partly inspired by Cristian Davide Conte.
This is an alternative algorithm which performs the summing numerically, without any conversion to strings (which is fine too!).
function sumOfDigits(number) {
if (parseInt(number) !== number || isNaN(number)) {
throw new Error('the given number is not integer');
}
if (number < 0) {
return -sumOfDigits(-number);
}
let sum = 0;
while (number > 0) {
let lastDigit = number % 10;
sum += lastDigit;
number = (number - lastDigit) / 10;
}
return sum;
}
It first ensures that the passed number is indeed an integer.
It handles the special case where a negative number is put in, by returning the negative checksum.
In each iteration the last digit is added to the sum and then that digit is subtracted from the number (which then has last digit 0) and the number is divided by 10 to remove the last digit. This is done until the number has been reduced to 0.
And what about arithmetics?
const num = 125;
const sum = (num - 1) % 9 + 1;
console.log(sum)
There isn't really a complete answer I can give you, but I can give you a workaround.
function customStrictEquality(value1, value2) {
if (value1 === 12 && value2 === 3) {
return true;
} else if (value2 === 12 && value1 === 3) {
return true;
} else if (value1 === value2) {
return true;
} else {
return false;
}
}
In the book Eloquent JS in the section of recursion, a program was given:
Consider this puzzle: by starting from the number 1 and repeatedly
either adding 5 or multiplying by 3, an infinite amount of new numbers
can be produced. How would you write a function that, given a number,
tries to find a sequence of such additions and multiplications that
produce that number? For example, the number 13 could be reached by
first multiplying by 3 and then adding 5 twice, whereas the number 15
cannot be reached at all.
I have following program which look like checks it, but I don't know how to make it print he sequence.
function tester (value, key) {
if (value == key) {
return 1;
}
else if (value > key) {
return 0;
}
else {
if ( tester(value+5, key) || tester(value*3, key) ) {
return 1;
}
return 0;
}
}
Your version is a little odd to me, returning 1 or 0 rather than true or false. Are you mostly used to a language that conflates booleans with such integers? But it looks like it should work.
I would write it a bit differently. I generally prefer my recursion to count down to smaller inputs. You can write a simple function to test the values like this:
const m3a5 = (n) => n < 1
? false
: n == 1
? true
: m3a5(n - 5) || (n % 3 === 0 && m3a5(n / 3))
console.log(m3a5(13)) //=> true
console.log(m3a5(15)) //=> false
console.log(m3a5(18)) //=> true
This should be entirely equivalent to yours, modulo the boolean/int differences.
With this one, you can can then expand it in a fairly straightforward manner to allow you to capture the steps:
const m3a5 = (n, steps = []) => n < 1
? false
: n == 1
? steps
: m3a5(n - 5, ['+5'].concat(steps))
|| (n % 3 === 0 && m3a5(n / 3, ['*3'].concat(steps)))
console.log(m3a5(13)) //=> ['*3', '+5', '+5']
console.log(m3a5(15)) //=> false
console.log(m3a5(18)) //=> ['*3', '+5, '+5', '+5']
Note that this will show one possible path, not all of them. For instance ['+5', '*3'] is another possible result for m3a5(18), one which you would get by switching the main branch to
: (n % 3 === 0 && m3a5(n / 3, ['*3'].concat(steps)))
|| m3a5(n - 5, ['+5'].concat(steps))
But if you want all the paths, that would be significantly different code.
You could store the sequence and if found the calculation return the sequence.
function tester(key, value = 1, sequence = value) {
if (value > key) {
return false;
}
if (value === key) {
return sequence;
}
return tester(key, value + 5, '(' + sequence + ' + 5)')
|| tester(key, value * 3, sequence + ' * 3');
}
console.log(tester(15));
console.log(tester(11));
console.log(tester(24));
console.log(tester(37));