DEV Community

Discussion on: Daily Coding Puzzles - Oct 29th - Nov 2nd

Collapse
 
aspittel profile image
Ali Spittel

Wednesday

Write a program to reverse the digits of a positive integer but without converting it to a string.

Collapse
 
clandau profile image
Courtney

probably not the best solution but it works. (unless you want leading zeros...but I'm assuming that's not the case since it wants a number).

function reverseNum(n) {
    const divisor = 10;
    let reversed = 0;
    let holder = [];
    while(n > 0) {
        holder.push(n % divisor);
        n = (Math.floor(n / divisor));
    }
    let place = Math.pow(10, holder.length-1);
    for(let i = 0; i < holder.length; i++) {
        reversed += (holder[i] * place);
        place /= 10;
    }
    return reversed;
}
Collapse
 
tux0r profile image
tux0r • Edited

As nothing in the question says that the result must still be an integer, why not make it an array instead? That would also elegantly solve the problem that an input that ends with a "0" would be chopped... or, even better, don't use any return value. After all, you did not ask for one.

#include <stdio.h>

void reverse_int(int in) {
    while (in > 0) {
        printf("%d", in % 10); /* modulo 10 ... */
        in /= 10; /* ... and move one digit. */
    }
}

/* PoC: */
int main(void) {
    reverse_int(1234567890);

    return 0;
}

Output:

0987654321
Collapse
 
kspeakman profile image
Kasey Speakman • Edited

F#

let rec loop rev i =
    if i = 0 then rev
    else loop (rev * 10 + (i % 10)) (i / 10)

// usage, returns 987654321
let reversed = loop 0 123456789
  • Uses a recursive loop. (F# will TCO to a while loop on compile)
  • i % 10 gets the right-most digit of i
  • rev * 10 shifts the numbers left, with right-most zero
  • i / 10 shifts the numbers right, dropping right-most digit

I happened to remember these little number tricks from a previous challenge. This is basically using integers as digit stacks.

Collapse
 
dance2die profile image
Sung M. Kim • Edited

Thank you, Ali.
This has been one of the most fun challenges.

Took me awhile but here is the C# version.

The gist is that, remainder is calculated for each digit, stored in a stack (LIFO - last in first out) to reverse the remainder.

Lastly the total is reconstructed from the stack.

Runnable code on .NET Fiddle

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var a = new int[] {123456, 5, 654321, 1234567890};

        foreach (var n in a) {
            Console.WriteLine($"Reversed = {Reverse(n)}");  
        }
    }

    private static int Reverse(int input) {
        var stack = BuildStack(input);
        return ConvertStackToNumber(stack);
    }

    private static Stack<int> BuildStack(int input) {
        var power = 0;
        var stack = new Stack<int>();

        while (true) {
            power++;
            var modBy = (int) Math.Pow(10, power);
            var divisior = (int) Math.Pow(10, power - 1);

            var remainder = (input % modBy) / divisior;
            if (remainder == 0 && power != 1) break;

            stack.Push(remainder);
        }
        return stack;
    }

    private static int ConvertStackToNumber(Stack<int> stack) {
        var total = 0;
        var power = 0;
        while (stack.Count > 0) {
            var current = stack.Pop();
            total += current * (int)Math.Pow(10, power++);
        }
        return total;
    }
}
Collapse
 
aspittel profile image
Ali Spittel

Oh that's a really cool approach!

Collapse
 
choroba profile image
E. Choroba
#! /usr/bin/perl
use warnings;
use strict;

sub rev {
    my ($x) = @_;
    my $r = my $z = 0;
    my $start = 1;
    while ($x) {
        ! ($r *= 10) and $z += $start or undef $start;
        $r += $x % 10;
        $x = ($x - $x % 10) / 10;
    }
    return '0' x ($z - 1) . $r
}

use Test::More tests => 4;
is rev(3), 3;
is rev(123456789), 987654321;
is rev(4444), 4444;
is rev(1000), '0001';
Collapse
 
aspittel profile image
Ali Spittel

My Python solution:

def reverse_number(num, running_value=0):
    if num == 0: 
        return running_value // 10
    quotient, remainder = divmod(num, 10)
    running_value += remainder
    return reverse_number(quotient, running_value * 10)

print(reverse_number(123456))
print(reverse_number(5))
Collapse
 
dance2die profile image
Sung M. Kim

And now this is... 😮

Thread Thread
 
tux0r profile image
tux0r

... broken.

Collapse
 
tux0r profile image
tux0r
>>> print(reverse_number(1234567890))
987654321

You did not pass.

Thread Thread
 
dance2die profile image
Sung M. Kim • Edited

987654321 is how I expect it to work though without the 0 in the beginning as you should return a positive integer.

Thread Thread
 
tux0r profile image
tux0r

That was not a part of the question, so I would say that the result should still start with a 0.

Thread Thread
 
aspittel profile image
Ali Spittel

the positive integer shouldn't have a leading zero I don't think. It's at least up to interpretation.