Rust Interview Puzzles: Reverse a number

Rust Interview Puzzles: Reverse a number

Problem

We need to reverse a provider integer (i32) number num without converting it to a string or using axillary data structures. Also, we should take care of a possible i32 overflow when reversing the number - in that case, we should return 0.

Examples:

Input numOutputExplanation
12344321
12021
11
00
-1-1
-1234-4321
14638474122147483641
14638474130The reversed number would be greater than i32::MAX = 2147483647
-14638474130The reversed number would be less than i32::MIN = -2147483648

Solution

fn reverse_number(mut num: i32) -> i32 {
    let mut num_reversed: i32 = 0;
    while num != 0 {
        if num_reversed.abs() > i32::MAX / 10 {
            return 0;
        } else {
            num_reversed = num_reversed * 10 + num % 10;
            num /= 10;
        }
    }
    num_reversed
}

Explanation

This puzzle is similar to what we implemented in Check if a number is Palindrome puzzle. The idea is to decompose the original num in the loop, digit by digit from the right, using the division and modulo operations, and at the same time compose a reversed number from these digits. The catch here is to avoid a possible i32 overflow in case we try to reverse some very large i32 number like 1463847413. This number itself could fit in i32 range (it is less than i32::MAX = 2147483647) but the reversed number would not fit. In that case, we should return 0.

Let's consider the process step by step for num = 1234.

  • On the 1st iteration, num_reversed = num_reversed * 10 + num % 10 = 0 * 10 + 1234 % 10 = 4. This is the last digit of 1234. Then we also update num = num / 10 = 1234 / 10 = 123.

  • On the 2nd iteration, num_reversed = num_reversed * 10 + num % 10 = 4 * 10 + 123 % 10 = 43. That is the last 2 reversed digits of 1234. Then we also update num = num / 10 = 123 / 10 = 12.

  • On the 3rd iteration, num_reversed = num_reversed * 10 + num % 10 = 43 * 10 + 12 % 10 = 432. That is the last 3 reversed digits of 1234. Then we also update num = num / 10 = 12 / 10 = 1.

  • On the 4th iteration, num_reversed = num_reversed * 10 + num % 10 = 432 * 10 + 1 % 10 = 4321. That is our full reversed number. Then we also update num = num / 10 = 1 / 10 = 0. End of the while loop.

  • The reversed number 4321 is returned from the function.

To process a possible i32 overflow scenario, we also have num_reversed.abs() > i32::MAX / 10 check, which, if satisfied, would stop the flow and return 0 from the function. Without this check num_reversed * 10 multiplication could go outside i32::MAX (or i32::MIN) range, so this condition checks beforehand if the overflow would happen or not.


Rust Playground with this code