'isLucky task - CodeSignal; keeps running true even with if else statement defaulting to false

I'm doing the isLucky task on CodeSignal and my code keeps returning true. What can I do to fix this?

Task: A ticket number is considered lucky if the sum of the first half of the digits is equal to the sum of the second half.

Given a ticket number n, determine if it's lucky or not.

I've tried switching the order of the code using

if(first == second) {
return true;
} else { 
return false;
}


function isLucky(n) {
    var half = n.length/2;
    var first = 0;
    var second = 0;
    for(var i = 0; i < half; i++) {
        first += n[i];
    }
    for(var j = half+1; j < n.length; j++) {
        second += n[j];
    }
    if(first != second) {
        return false;   
    } else {
        return true;
    }
}

One of the practice tests is n = 239017; I expected it to return false, but it returns true.



Solution 1:[1]

n is a number, and numbers don't have length properties or numerical indices. With that in mind, we see that the important part of your code never runs:

function isLucky(n) {
    var half = n.length/2; // n.length is undefined; undefined / 2 is NaN

    var first = 0;
    var second = 0;

    // (0 < NaN) is false; this loop never runs
    for(var i = 0; i < half; i++) {
        first += n[i];
    }

    // NaN + 1 is NaN, (NaN < undefined) is false; this loop never runs
    for(var j = half+1; j < n.length; j++) {
        second += n[j];
    }

    // Nothing has happened since first and second were both set to 0; return true
    if(first != second) {
        return false;   
    } else {
        return true;
    }
}

Converting n to a string fixes those problems, but now isLucky always returns false. Reading through the function, we expect first to contain the sum of the digits of the first half of n, and second the sum of the second half. Log the values of first and second before the function returns to check that assumption:

function isLucky(n) {
  n = n.toString();
  var half = n.length / 2;
  var first = 0;
  var second = 0;
  for (var i = 0; i < half; i++) {
    first += n[i];
  }
  for (var j = half + 1; j < n.length; j++) {
    second += n[j];
  }
  
  console.log(first, second);
  if (first != second) {
    return false;
  } else {
    return true;
  }
}

console.log(isLucky(239017));

Those aren't sums. They're not even numbers. (The stack snippet console doesn't show it, but Chrome and Firefox's consoles log numbers in color and strings in black. Those are strings.)

This is because n[i] is a string, and + is concatenation for strings. Convert them to numbers with Number(n[i]) or +n[i], and isLucky(239017) works. Other numbers still have problems, though:

function isLucky(n) {
  n = n.toString();
  var half = n.length / 2;
  var first = 0;
  var second = 0;
  for (var i = 0; i < half; i++) {
    first += +n[i];
  }
  for (var j = half + 1; j < n.length; j++) {
    second += +n[j];
  }
  
  console.log(first, second);
  if (first != second) {
    return false;
  } else {
    return true;
  }
}

console.log('239017 (should be false):', isLucky(239017));
console.log('123321 (should be true):', isLucky(123321));
console.log('123933 (should be false):', isLucky(123933));

Looks like the first digit of the second half isn't being included in the sum. You can see that happening in the earlier version, as well: with second initialized to 0, we would expect a string concatenation with the second half of '239017' to be '0017', but we got '017' instead.

Start the second loop at half instead of half + 1 (and drop the diagnostic logging), and isLucky works properly:

function isLucky(n) {
  n = n.toString();
  var half = n.length / 2;
  var first = 0;
  var second = 0;
  for (var i = 0; i < half; i++) {
    first += +n[i];
  }
  for (var j = half; j < n.length; j++) {
    second += +n[j];
  }
  
  if (first != second) {
    return false;
  } else {
    return true;
  }
}

console.log('239017 (should be false):', isLucky(239017));
console.log('123321 (should be true):', isLucky(123321));
console.log('123933 (should be false):', isLucky(123933));

Solution 2:[2]

JavaScript Solution

function isLucky(n) {    
    let count = 0;
    n = String(n).split('').map(t => {return parseInt(t)});
    n.forEach( (el, i) => { (i < n.length / 2) ? count += el : count -= el });
    return count == 0;
}

Solution 3:[3]

Solution in JS

function isLucky(n) {
    const b = n.toString().split('')
    const y = b.length / 2;
    let c1 = 0
    let c2 = 0
    b.map((e, i) => {
        if (i+1 <= y) c1 += parseInt(e);
        if (i+1 > y) c2 += parseInt(e);
    })
    return c1 === c2
}

Solution 4:[4]

function solution(n) {
// array from string n
    const nArr = n.toString().split('');
// split the nArr into two halfs
    const firstHalf = nArr.splice(0, nArr.length / 2);
    const secondHalf = nArr.splice(nArr.length / 2 - 1, nArr.length);
// Using reduce to sum both halfs from nArray, then compare them
    return firstHalf.sort( (a, b) => b - a).reduce( (prev, curr) => Number(prev) +  Number(curr) ) == 
            secondHalf.sort( (a, b) => b - a).reduce( (prev, curr) => Number(prev) +  Number(curr) );
}

Solution 5:[5]

(1). length property only works when n is in String or Array not Integer
var half = n.length/2;

need to convert Integer to string first.

n = n.toString();


(2). when you need any particular numeric character from a string, you need to typecast from character to integer.

sum½ += parseInt(n[index])


(3). first sum is stop at half, not checking character at exact index = half.
so second sum should start with index = half, instead of half + 1.

for(var j = half; j < n.length; j++) {


(4). you can optimize your last condition.
when boolean result is depending on condition, you can do

return (first == second);

function solution(n) {
    n = n.toString();
    var half = n.length/2, first = 0, second = 0;
    for(var i = 0; i < half; i++) {
        first += parseInt(n[i]);
    }
    for(var j = half; j < n.length; j++) {
        second += parseInt(n[j]);
    }
    return first == second;
}
console.log(solution(11));
console.log(solution(1230));
console.log(solution(134008));
console.log(solution(999999));
console.log(solution(123321));
console.log(solution(239017));
console.log(solution(261534));
console.log(solution(100000));

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 AuxTaco
Solution 2
Solution 3 Wisman Nur Abdul Kholik
Solution 4
Solution 5 b m gevariya