Home > Back-end >  Why function returns wrong array of numbers if that number is big
Why function returns wrong array of numbers if that number is big

Time:01-17

I am working to solve a problem, I have an array of numbers for example [1, 2, 3] and I need to make from that array number 123 and add 1 and than return it like [1, 2, 4]. My code work with small numbers but with big it returns wrong number. Why?

var plusOne = function(digits) {
  let num = parseInt(digits.join(''))
  num = num   1
  let arr = num.toString().split().join(',')
  let incrementedArr = []
  for (let i = 0; i < arr.length; i  ) {
    incrementedArr.push(arr[i])
  }

  return incrementedArr;
};

When input is

[6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3]

my function returns

[6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,0,0,0]

instead of

[6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,4]

why I have three zeros in the end? Thank you!

CodePudding user response:

The problem is with the way you are converting the number back to an array. Your code is using the split() method, which expects a separator as the argument, but you are passing an empty string. This causes the method to split the number into an array of characters, rather than numbers.

You should use the map() method instead, like this:

let incrementedArr = Array.from(num.toString()).map(Number);

This will convert the number back to a string, and then use the map() method to convert each character back to a number.

Another issue is with the way you are incrementing the number. You are incrementing the number after converting the array to a number. Instead of that you should use the last element of the array and increment it by 1 and use the rest of the array as it is.

let incrementedArr = digits.slice()
incrementedArr[incrementedArr.length-1]  = 1

Also, you can use spread operator to return the incremented number.

return [...incrementedArr];

Here is the final code:

var plusOne = function(digits) {
  let incrementedArr = digits.slice()
  incrementedArr[incrementedArr.length-1]  = 1
  return [...incrementedArr];
};

I hope this helps!

CodePudding user response:

As the maximum JavaScript precision would be exceeded by a number of this size, see @Barmar's comment, you may have to perform the addition and the carry-over manually and below is one approach:

const 
    d0 = [6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3],
    d1 = [6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,9],
    d2 = [6,1,4,5,3,9,0,1,9,5,1,8,6,7,9,9,9,9,9],
    
    plusOne = d => {
       let adds = d.map((n,i,a) => i === a.length - 1 ? 1 : 0), newd = d;
       do {
           newd = newd.map((n,i) => n   adds[i]);
           adds = adds.fill(0);
           adds = newd.map((n,i) => n > 9 ? 1 : 0);
           adds.push( adds.shift() );
           newd = newd.map(n => n > 9 ? 0 : n);
       } while( !adds.every(e => e === 0) );           
       return newd;
    };
    
console.log( plusOne( d0 ) );

console.log( plusOne( d1 ) );

console.log( plusOne( plusOne( d1 ) ) );

console.log( plusOne( d2 ) );

CodePudding user response:

This is probably what was meant to be done in the exercise

function plusOne(digits) {
  const copy = [...digits]
  for (let i = copy.length - 1; i >= 0; i -= 1) {
    if (copy[i] < 9) {
      copy[i]  = 1
      for (let j = i   1; j < copy.length; j  = 1) {
        copy[j] = 0
      }
      return copy
    }
  }
  return [1, ...'0'.repeat(copy.length)]
}

console.log(plusOne([6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3]).join(''))
console.log(plusOne([6,1,4,5,3,9,0,1,9,5,1,8,6,7,9,9,9,9,9]).join(''))
console.log(plusOne([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]).join(''))

CodePudding user response:

You can use BigInt:

const plusOne = digits => Array.from(String(BigInt(digits.join(''))   1n), Number)

console.log(plusOne([1, 2, 3]))
console.log(plusOne([6, 1, 4, 5, 3, 9, 0, 1, 9, 5, 1, 8, 6, 7, 0, 5, 5, 4, 3]))

  • Related