Understanding negative numbers in recursion - javascript

I'm just getting my head around recursion in javascript using the book Eloquent Javascript but don't fully understand what is happening to the negative number (-1) in this fiddle:
http://jsfiddle.net/greenhulk01/kg5ton1t/
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);
}
};
console.log(isEven(50));
// → true
console.log(isEven(75));
// → false
console.log(isEven(-1));
// → false
I understand everything that is going on in this recursion except for how "return isEven(-n);" is being handled. Using console.log i can see it is returned as undefined so not sure why it is caught by the false statement.
Any pointers to help my understanding would be really appreciated.
Cheers.

isEven(-n) just takes advantage of the fact that if -n is even, n is even, too. So basically isEven(-10) calls isEven(10)
BTW: Did you try isEven(1.5)? I'd expect false, but I'd guess you'd get a stack overflow. I'd write this as
function isEven(n) {
if (n < 0) {
return isEven(-n);
}
if (n >= 2) {
return isEven(n - 2);
}
return n == 0;
};
BTW 2: Without using recursion, you could just write
function isEven(n) {
return n % 2 == 0;
}

Related

How to return NaN

I'm working on a codewars problem-here's the question:
-Write a function that accepts two integers and returns the remainder of dividing the larger value by the smaller value.
-Division by zero should return NaN.
I have the first part figured out, but how do I return NaN if I divide by 0? I don't know a lot about NaN and I'm pretty new to JavaScript.
function remainder(n, m){
if (n > m) {
let answer = n % m;
if (m === 0) {
return undefined;
}
else {
return answer;
}
}
else if (m > n) {
let answer = m % n;
if (n === 0) {
return undefined;
}
else {
return answer;
}
}
else {
let answer = n % m;
return answer;
}
}
Edit: solved, answer is below
Welcome to our community!
NaN stands for Not-a-Number and it is a property of the global object(in order to understand more about the global object, I would recommend reading about Scopes).
You could access NaN like this:
window.NaN => from a browser
Number.NaN
NaN
If you want to check if a number is NaN you could use: isNaN.
If you want to use it in a function you can just do
function test(x){
if(isNaN(x)){
return NaN;
}
return x;
}
To come back to your problem, you could do something like this:
function calculateRemainder(a,b){
return a>b ? a % b : b % a
}
Where % is known as the remainder operator about which you can read more here. This operator returns NaN if you try to divide by 0 or to operate with Infinity.
The following operations return NaN:
NaN % 2
Infinity % 0
10 % 0
Infinity % Infinity
The problem is that % is not the divider syntax, but this is /.
I created a basic example for you:
In this example, the console logs "divider is 0"
function divider(up, down) {
if (down == 0) {
console.log("divider is 0");
return NaN
} else {
console.log(up / down);
}
}
divider(5, 0);
But here, it will log 2.5
function divider(up, down) {
if (down == 0) {
console.log("divider is 0");
return NaN
} else {
console.log(up / down);
}
}
divider(5, 2);
This is my answer (with help from the comments on my question), and it worked. Thank you for your help!
function remainder(n, m){
if (n > m) {
let answer = n % m;
if (m === 0) {
return NaN;
}
else {
return answer;
}
}
else if (m > n) {
let answer = m % n;
if (n === 0) {
return NaN;
}
else {
return answer;
}
}
else {
let answer = n % m;
return answer;
}
}

How do two ternary operators work together in JS?

So I was doing a code problem online and one of the solutions showed the following
function electionsWinners(votes, k) {
var max=Math.max(...votes)
var r=votes.filter(x=>x+k>max||x===max).length
return k?r:r==1?1:0
}
I don't think the specifics of the problem are relevant, I'm more interested in how the return statement works. I don't understand at all what gets returned, it seems that 2 ternary operators are being used but I'm not sure, can anyone help me understand how exactly this return statement functions?
Yes 2 ternary operators
return k?r:r==1?1:0
i will put the code with complete IF
if(k) //not is null
return r;
else
{
if(r==1)
return 1;
else
return 0;
}
If you convert it to if else statement then you'll better understand what's going on:
if (k) {
return r;
} else if (r === 1) {
return 1;
} else {
return 0;
}
Or
if (k) {
return r;
}
if (r === 1) {
return 1;
}
return 0;
You can look at
k?r:r==1?1:0
as a single expression. Each ? is connected to its immediately following :, so it's equivalent to:
k ? r : (r==1 ? 1 : 0)
where the second conditional operator takes effect only if the k is falsey. In that second conditional, if r is 1, 1 is returned, else 0 is returned.
Might be clearer with indentation:
return (k
? r
: (r == 1
? 1
: 0
)
);
The first test is k ? is k not 0/undefined/null? If so, return r (r) else : if r is 1 (r==1 ?) return 1 (1) otherwise return 0 (0))

What is a better way to get a even number?

So I have been reading this book named: Eloquente JavaScript, and to be true somethings in this book seems quite complex. There was this challenge were I had to wright a function that showed true or false depending if the value was even or not. My version is quite shorter then the one from the book. What should be the best way of doing this? Also why did he do it like this?
Eloquente JavaScript 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);
}
console.log(isEven(50));
console.log(isEven(75));
console.log(isEven(-1));
My own code:
function even(num) {
if (num % 2 == 0){
return true;
}
else{
return false ;
}
};
console.log(even(17));
console.log(even(10));
console.log(even(-33));
console.log(even(-40));
function even(num) {
return num % 2 === 0;
}

How does a negative value turn positive by calling it negative in the console?

i used Math.abs but I fail and found this solution, I am following on eloquent javascript and how did negative value is turned to positive, here is the code:
function isEven(n) {
if (n == 0) {
return true;
}
else if (n == 1) {
return false;
}
else if (n < 0) {
console.log(-n);
return isEven(-n); // turn -3 to 3?
}
else {
return isEven(n - 2);
}
}
console.log(isEven(-3));
Here you are a simpler test case:
> console.log( -(-3) );
3
This is not a JavaScript peculiarity, it's how maths work.
Console has nothing to do with this.
Think back to your math class. -n is a shortened expression for (-1) * n. If you multiply two negative numbers, the result is a positive number - and since you're multiplying by negative 1 (where positive 1 is identity for multiplication), the result is the same number, but positive.
Since you're checking if (n < 0) before you multiply by -1, you'll always get a positive number.
However, this is almost definitely not what you want - the code you found seems to be an example of how to use recursion to solve common problems. In real-world Javascript, you'd want something more like this:
function isEven(x)
{
return (Math.abs(x) % 2) === 0;
}
it has to be recursion
Lets break the mold! Using -1 instead of 2. Assuming an integer;
function isEven(x) {
if (x === 0) return 1; // ended
return -1 * (isEven(Math.abs(x) - 1) ? 1 : -1) === 1;
}
Other fun ways to test for even that don't need 2 or mod/remaineder
function isEven(x) {
return Math.round(Math.sin(5 * x / Math.PI)) === 0;
}
An O(log n) recursion
function isEven(x, a) {
if (!a) a = [true, false];
if (a.length > x) return a[x];
return isEven(x, a.concat(a));
}

Prime factor in javascript, why is this case not working?

I'm writing a primality checker in in j/s and I was wondering why I'm getting true as a return for when I test 55... It seems to work fine for all the other cases I checked just not 55, can someone tell me where I went wrong?
var isPrime = function(num){
if (num === 2){
return true;
}
else if(num%2 === 0){
return false;
}
else{
var i = 2;
while(i<num){
if((num/i) % i === 0 ){
return false;
}
i++
}
return true;
}
};
Thanks in advance and apologies for the noobness!
if((num/i) % i === 0 ){
return false;
}
What is this case?
Shouldn't it be
if(num % i === 0 ){
return false;
}
Just as #Andrey pointed out, your if statement inside the while loop is not correct. For 55 at i=5 you should get false for 55 being prime, but 55/5 % 5 == 1 Also you could use just == instead of === for logical equals, since === checks if both values and type are equal, which is not necessary here.
Try this.
var isPrime = function isPrime(value) {
var i = 2;
for(i; i < value; i++) {
if(value % i === 0) {
return false;
}
}
return value > 1;
};
Even if your bug may be solved, I'd recommend to think about some other aspects to optimize your code:
Clarify your corner cases: In the beginning, check for n<2 -> return false. At least to math theory primes are defined as natural number larger then 1, so 1 is by definition not a prime like all the negative numbers. Your code won't handle negative numbers correctly.
You don't have to check all divisors up to n-1. You can obviously stop checking at n/2, but there are even proofs for tighter bounds which means you can stop checking already at √n if I'm right. To further optimize, you don't have to check even divisors >2.
else {
var i = 3;
while ( i < num/2 ) {
if( num % i == 0 ) {
return false;
}
i+=2;
}
return true;
}
See https://en.wikipedia.org/wiki/Primality_test for details about testing of primes.
P.S: I just wrote the code here in the text box, but it looks like it might work.

Categories