Reverse Integer

The task is taken from leetcode

Given a 32-bit signed integer, reverse digits of an integer.

Example 1:

Input: 123

Output: 321


Example 2:

Input: -123

Output: -321


Example 3:

Input: 120

Output: 21


Note:

Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−2^31, 2^31 − 1]. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.

My solution

/**
* @param {number} x
* @return {number}
*/
const reverse = x => {
if (x === undefined || x === null) { return; }
if (x < 10 && x >= 0) { return x; }

const num = [];
const dissectNum = n => {
if (n <= 0) { return; }
const y = n % 10;
num.push(y);
return dissectNum(Math.floor(n / 10));
};
dissectNum(Math.abs(x));
let tmp = 0;
const maxPow = num.length - 1;
for (let i = 0; i < num.length; i++) {
tmp += num[i] * Math.pow(10, maxPow - i);
}
const result = (x < 0 ? -1 : 1 ) * tmp;
return result > Math.pow(-2, 31) && result < (Math.pow(2, 31) - 1)
? result
: 0;
};


• The question states that the input is a number 32 signed int so checking for undefined or null is a waste of time.

The solution is a little long. Some of it due to not being familiar with some old school short cuts.

-JavaScript numbers are doubles but when you use bitwise operations on them they are converted to 32 bit signed integers. This gives you a very easy way to check if the result has overflowed.

const signedInt = value => (value | 0)  === value; // returns true if int32

• A 32 bit int can store 9 full decimal digits, with an extra digit 1 or 2, and a sign. you dont need to use an array to hold the reversed digits you can store them in the reversed number as you go.

• JavaScript can handle hex 0x10 === 16, decimal 10 === 10, octal 010 === 8 and binary 0b10 === 2 (oh and BIG ints 10n === 10) Hex makes realy easy to remember the lowest and highest int for a given size.

Not that you need them to solve the problem, just some handy info.

Some common ways of writing min max 32Ints

 const MIN = Math.pow(-2, 31), MAX = Math.pow(2, 31) - 1;

// negative
-0x80000000 === MIN;      // true
(0x80000000 | 0) === MIN; // true. Coerce from double to int32
1 << 31 === MIN;          // true. Shift 1 to the highest (MSB) bit for negative

//positive
0x7FFFFFFF === MAX; // true
~(1 << 31) === MAX; // true  Flips bits of min int32


Rewrite

With that info you can rewrite the solution as

function reverseDigits(int) {
var res = 0, val = Math.abs(int);
while (val > 0) {
res = res * 10 + (val % 10);
val = val / 10 | 0;
}
res *= Math.sign(int);
return (res | 0) === res ? res : 0;
}


I'd just use string manipulation on this, with a simple conditional for the edge cases.

var reverse = n => {
const s = parseInt([..."" + n].reverse().join(""));
return s >= 2 ** 31 ? 0 : Math.sign(n) * s;
};


The approach is to stringify the number, arrayify the string, reverse it, re-join the array into a string and finally parse the reversed string to an integer. parseInt called on a string such as "546-" will strip the trailing -. Then, handle overflow and positive/negative conditions and return the result.

In short, avoid overcomplication and take advantage of high-level language features when possible.

Both answers require you to use Math.sign. To avoid compatibility issues with some browsers, you could add the following script in your solution.

if (Math.sign === undefined) {
Math.sign = function ( x ) {
return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : +x;
};
}