Need to understand better this code - javascript

I'm reading a JavaScript book, I'm new at this, so I got to the part of recursion and I get how recursion works but is not that part is hard to me is the math part.
This is the code:
function isEven(n) {
if (n == 0)
return true;
else if (n == 1)
return false;
else if (n < 0)
return isEven(-n);
else
return isEven(n - 2);
}
lets say I pass to the function 50 as a value right
isEven(50);
That give me true... how come 50 == 0 is true or 75 == 1 is false... I really don't get it.

When you pass 50 to this function, it goes to the last block (else) and is executed recursively. When you write return isEven(n - 2);, you execute isEven(48), and then the next time isEven(46) and so on right upto the point where you reach isEven(0).
This calls the first if block and you get true as your output. The true is returned by isEven(0), followed by isEven(2) (becuase when you executed isEven(2) you ended up going to return isEven(0)) and this bubbles up the stack to finally return the output of isEven(50) as true.

This code is kind of a long way of checking whether a number is even. It relies on the fact that if a number is even and you continually subtract 2 from it, you'll eventually reach 0. Otherwise, if your number is odd, subtracting 2 repeatedly will eventually reach 1.
So if the number you pass is greater than 0, it will send the next number (n - 2) back to the function again, until it either reaches 0 or 1. Then we stop.
If the number is negative, we just flip the sign and do the same process.

This is an interesting way of applying recursion to an issue that could be solved as simply as:
return n % 2 == 0
Basically, it works by having two base cases: n == 0 and n == 1. Both of these are "known", so they just return true or false. If the number is negative, do a recursive call with the sign reversed (isEven(-n)). Otherwise, you just subtract 2 (isEven(n - 2)). This works because any odd number minus 2 is still an odd number, and even number minus 2 is still even. So, you simply keep subtracting 2 from n until n fits one of the base cases (n == 0 or n == 1).
if (n == 0) // base case
return true;
else if (n == 1) // base case
return false;
else if (n < 0) // reverse sign, call recursively
return isEven(-n);
else // default, subtracts 2, calls recursively
return isEven(n - 2);

Use this tool to visualize your code and you'll see where you're getting hung up.
Click the Forward > button after the page loads to step through your code.

You can simplify the function by using % operator
let isEven = n => !(n % 2);

Related

problem with the logic behind Fibonacci nth term

const fibonacci = function (n) {
n = parseInt(n)
if (n < 0) return 'OOPS'
if (n < 2) return n
else {
return fibonacci(n - 1) + fibonacci(n - 2)
}
}
this is a recursive function for solving the problem but I am finding it difficult to understand why the base case must evaluate to 1. I get the syntax but I don't get the logic behind the solution.
The base case must evaluate to 1 because the first two terms of the Fibonacci sequence are 1, 1 (or in some cases 0, 1, which gives the same sequence starting with a zero).
Unrelated to your question, but the way you wrote that will be very slow because it will recalculate Fibonacci numbers lower than the target many, many times. If this must be recursive, then use memoization so each value is only calculated once.

Javascript: How to recursively return a counter?

In the example below, I don't want to make a counter as a param. Rather, I just want to return '+ 1' each time so that what gets returned is the number of steps it takes. My issue lies with the base case. If I do return + 1, I get the correct number of steps plus one additional step so I tried just return but that delivers NaN. Is it even possible?
var numberOfSteps = function(num) {
if (num == 0) {
return;
} else {
if (num % 2 == 0) {
return 1 + numberOfSteps(num/2);
} else {
return 1 + numberOfSteps(num - 1);
}
}
};
edit : The goal is to track how many steps it takes to reduce a number to 0. If it's even, divide by 2 or else subtract by 1. Ultimately, I want to return the number of steps it takes for any given number to get reduced to 0 following those rules
I hope the point has gotten through in the long comment thread and other answers that return + 1 is equivalent to return (+1), that is, return the integer positive one. And since there are no steps to take once you've reached zero, +1 is the wrong answer. Similarly, a plain return is functionally equivalent to return undefined. But undefined is not a number, and you're going to run into problems if you later try to add 1 to it. So the solution from the comments or other answers to return the correct number of steps, which in this case 0, will fix your code.
I would like to point out another way to solve this, though:
const numberOfSteps = (n) =>
n <= 0
? 0
: 1 + numberOfSteps (n % 2 == 0 ? n / 2 : n - 1)
console .log (numberOfSteps (12))
There are superficial differences here from the other solutions, such as using an arrow function, using a conditional statement (ternary) rather than if-statements, and using <= 0 instead of < 0 to avoid possible infinite loops on negative numbers.
But the fundamental difference is that this code only has one recursive branch. I think this is a better match to the problem.
We can think of this as a function which answers "How many steps does it take to reach 0 from our input number if each step cuts even numbers in half and subtracts one from odd ones?" Well that logically leads to a base case (we're already at 0) so have to return 0, and a recursive one (we're at some positive integer) so have to add 1 to the total steps required from our next entry.
By doing this single recursive call and adding one to the result, we make it clearer what the recursion is doing.
If this is unclear, then this alternative might show what I mean:
const takeStep = (n) =>
n % 2 == 0 ? n / 2 : n - 1
const numberOfSteps = (n) =>
n <= 0
? 0
: 1 + numberOfSteps (takeStep (n))
Think you just need to return 0 when it's...zero.
var numberOfSteps = function(num) {
if (num == 0) {
return 0;
} else {
if (num % 2 == 0) {
return 1 + numberOfSteps(num/2);
} else {
return 1 + numberOfSteps(num - 1);
}
}
}
return + 1 maybe doesn't do what you think it does: it returns the number 1. + here means positive not negative, there is no addition or subtraction going on. It will also give you one too many steps.
return; by itself returns undefined, which when converted to a Number, translates to NaN, because, well, it's not a number.

Why is the `n===0` used, as `-0===0` and `0===0` are both true?

function isNegZero(n) {
n = Number( n );
return (n === 0) && (1 / n === -Infinity);
}
I am reading the book You don't know JS and found this piece of code there. This is the function to check if the passes number is a -0. I failed to understand as to why the first condition in the comparison is mentioned as it is always going to be true (unless I am wrong in understanding it). Please help.
It’s always going to be true for zero. You want isNegZero(n) to not only be false for +0, but also for any number that is not zero.
> let n = -Number.MIN_VALUE
> n === 0
false
> 1 / n === -Infinity
true
The return value is the two comparisons '&&'ed together. Since it short circuits, if any number outside of 0 or -0 is passed, it will run the first comparison and then return false without ever needing to look at the second.

How do I modify a function to return true if the given decimal is even when it is rounded to an integer and false otherwise?

I'm working on a Javascript exercise. I am trying to modify a function to return true when the given decimal is rounded to an even number and false when it is not.
So far I have
function isRoundedNumberEven(decimal){
}
console.log(isRoundedNumberEven(2.2), '<-- should be true');
console.log(isRoundedNumberEven(2.8), '<-- should be false');
You have described two steps.
Round the number. This is easily achieved with Math.round()
Determine if it's even or odd. The easiest way to determine this is to divide by 2 and check the remainder. If the remainder is zero, then the number is even. Otherwise, it is odd.
The way you do this is using the modulo operator % - in this case, roundedNumber % 2 would give you the remainder when dividing by 2.
You just need to check if this remainder is 0 or 1, and since you want to "return true if the number is even," then the easy way is return roundedNumber % 2 === 0;
I've provided the tools. Over to you now to assemble them in the right way.
There are two key functions you need here: Math.round(decimal) and the modulo function: "%".
The first will round a decimal value. So, Math.round(2.2) == 2, and Math.round(2.8) == 3.
The second will find the remainder after whole-number division of a number. So, 2%2 == 0, and 3%2 == 1.
Hence, the contents of your function should be:
return Math.round(decimal) % 2 === 0;
function isRoundedNumberEven(decimal){
if((Math.round(decimal)%2) == 0) {
return true;
}
return false;
}

javascript: understanding the flow of a fibonacci recursive statement

I eventually want to get the hang of dynamic programming but before that, I am having a hard time understanding the flow of this. I understand recursion but I'm having trouble understanding the flow of this:
function fib(n) {
if (n == 0) return 0;
if (n == 1) return 1;
return fib(n - 1) + fib(n - 2);
}
console.log(fib(3));
if I have a small integer of 3, it does not pass those 2 conditionals so it hits return fib(n-1)+fib(n-2); So to my understanding, that will go through the first part of that first: fib(n-1) (3-1 = 2)... 2 does not satisfy either of those conditionals so it runs fib(n-1) (2-1 = 1). 1 DOES satisfy one of the conditionals so it returns 1 and breaks that part of it.
Now to to the next part: fib(n-2) . (3-2 = 1). 1 does satisfy one of the conditionals so it returns 1 .
So in the end, isn't that returning 1 + 1 ?
I'm not sure where I'm going wrong in my understanding.
You are correct in that fib(3) should return 2, because 2 is the 3rd number in the Fibonacci sequence (starting at 0)
It helps to write out it out as tree:
fib(3)
/ \
fib(2) fib(1)
/ \ \
fib(1) fib(0) 1
/ \
1 0
above you can see how each recursive call goes all the way to 0 or 1 before returning a result back up the previous layer.
One of my favorite ways to do this is to start with the base cases and go backwards:
fib(0); // => 0
fib(1); // => 1
Then we get to the default case:
fib(2); // == fib(1) + fib(0) == 1 + 0 ==> 1
fib(3); // == fib(2) + fib(1) == 1 + 1 ==> 2
fib(4); // == fib(3) + fib(2) == 2 + 1 ==> 3
This is much easier than trying to figure out fib(4) first since you need to nest. Looking at the function it's easy to see what to try.
Also know that calls to the same function doesn't get any special treatment. It runs until it returns with a value and it's arguments and local variables are local to the call so every fib call has its own n and it waits for the two calls to return to sum the results.

Categories