'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 Integervar 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 |