this doesn’t make sense, you have changes it to a string just above so you can’t compare to array, also [] == [] is false
I will get back later for more debugging, but for now I would suggest to make each step with a variable instead of chaining and see if at each step you have the expected value
I’m going to point on some things that can be improved, but my critques will be point by point and not holistic so improving upon them may not make your code pass necessarily, but I will probably look at it more holistically in a second comment.
//function upArray(arr) {
/*
This entire block could be done in one loop with one if statemnet
const checkIfnegative = (element) => element <= -1;
const checkIfSingleDigit = (element) => element > 9;
if (arr.some(checkIfnegative)) {
return null;
} else if (arr.some(checkIfSingleDigit)) {
return null;
}
*/
/*
this block would have the same result as: arr = arr.join("")
arr = arr
.map((num) => {
return num.toString();
})
.join("");
*/
/*
let num1;
variables can point towards the same object, but an anonymous object will always be unique so nothing could ever be the same as it, and I would also recommend using strict equality almost always
what you mean to check is arr.length, and you also reassigned your param so you no longer have a refernce to the orignal array (that may not be a problem I am simply pointing it out)
checking the length of the array would probably best done at the top
if (arr == []) {
return null;
} else {
parseFloat probably is not the best choice for number coercion here
num1 = parseFloat(arr) + 1;
num1 = num1
.toString()
.split("")
.map(function (i) {
return parseFloat(i);
});
}
return num1;
}
*/
The primary reason your code is failing is because you are attempting to make the array elements into one number, but some of the test have arrays that exceed Number.MAX_SAFE_INTEGER so when you attempt do math on them it just does it wrong. You will need to do some refactoring to get your code to pass, and if you would like I will tell you the logic behind my approach which did pass the test.
Hi, the interesting thing about any one data type, e.g. int, float, etc, is that they have a size cap. You’ve probably have heard of those limits such as the 32-bit int, or 64-bit int, etc. This actually means there’s an upper/lower limit to what a int can be.
In every language typically there will be a constant specifically storing the max/min value an integer can be, in Javascript it is MAX_SAFE_INTEGER and MIN_SAFE_INTEGER with 2^53-1 and 2(2^53-1) as values respectively.
But you probably realize we type large numbers here no problem, nor do we have any trouble multiplying/adding these large numbers beyond the storage limit comfortably with any calculator.
This is because large numbers can be stored as an array of n size, with n being the number of digits in the number.
Therefore your logic should not be to join the array together and work on the resulting number as that can result in int overflow, but you should work on the array itself.
Cases to consider:
what happens when you add the 1 and that digit becomes larger than 9?
And
What happens when that digit that becomes larger than 9 is the leading digit? (array element indexed at 0?)
This code below I presume would pass there test, but the challenge is on a version of node that does not accept BigInt which is also why I am just showing the code out right as it cannot be used. It is not dissimilar to the idea behind your approach, and is exactly how I attempted the challenge the first time, of course it failed then because of how big the numbers were. I did pass the test in way more similar to what @MatchaCrisp is describing .
function upArray(arr){
if (arr.length === 0) return null;
let sum = 0n;
let sumArr = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] < 0 || arr[i] > 9) return null;
sum += BigInt(arr[i]) * (10n ** BigInt(arr.length - (i + 1)))
}
sum++;
while (sum) {
sumArr.push(Number(sum % 10n));
sum /= 10n;
}
return sumArr.reverse();
}
This method is sure to be less efficient than not constructing a number at all, but it is more intuitive.
BigInt is a type of data for integers too big to be precisely saved in the usual number format, they are identified with an n after the number, like 10000000000n
the while loop is using the truthiness/falsyness of numbers, until sum is a number different from 0 the loop keeps going, when instead it becomes 0n it is falsy and the loop stops going
refactoring means to adjust code to fit environment, comment for clarity, remove redundant code etc etc. Basically it’s code cleanup/minor optimization. In this specific case tho as @caryaharper already stated:
…the challenge is on a version of node that does not accept BigInt…
So even if you refactor your original logic to use BigInt which would possibly encompass all testcases codewars environment may not accept it as correct.
And even if that logic does pass, it is inherently flawed due to anyone being able to add as many more elements to the array as they like and eventually exceed even the bigInt max limit.
function upArray(arr){
//checks to see if the array is empty
if (arr.length === 0) return null;
//Initializes the BigInt form of 0
let sum = 0n;
//Initializes an array that will become the return value
let sumArr = [];
//loops through the elements of arr
for (let i = 0; i < arr.length; i++) {
//checks for invalid values
if (arr[i] < 0 || arr[i] > 9) return null;
//creates a number from the array elements
//the math at the end gives the numbers place
sum += BigInt(arr[i]) * (10n ** BigInt(arr.length - (i + 1)))
}
//adds 1 to sum
sum++;
//loops while sum is not falsey, or in this case 0
while (sum) {
//grabs the lowest number off of sum and pushes it into sumArr
//it also turns said BigInt back into a number
sumArr.push(Number(sum % 10n));
//removes the lowest number off of sum
//for a normal number you will want to use Math.floor
//BigInt does not have floats
sum /= 10n;
}
//returns sumArr reversed as the method I used created the array backwards
//I could have used unshift, but I assumed it would have taken longer
return sumArr.reverse();
}
I have refrained from posting a solution outright and instead mentioned the correct logic, as I believe that the algorithm alone would be sufficient in coming up with the correct code, and that process would be good for learning.
More specifically,to solve this you are to add 1 to the array from the end to the beginning, taking into consideration the following two cases:
When the element becomes larger than 9 after adding 1
when that element that is larger than 9 is also the element at index 0.
Here is working code of the correct algorithm in action:
function upArray(arr){
if (arr.length===0) return null;
let carry=1;
for (let i = arr.length-1; i >= 0; i--) {
if (arr[i]>9 || arr[i]<0) return null;
if (carry>0) {
arr[i]+=carry;
carry=Math.floor(arr[i]/10);
arr[i]=arr[i]%10;
}
}
if (carry>0) arr.unshift(carry);
return arr;
}