views:

373

answers:

7

I came across a question "How can one reverse a number as an integer and not as a string?" Could anyone please help me to find out the answer.

+1  A: 
using System; 

public class DoWhileDemo {   
  public static void Main() { 
    int num; 
    int nextdigit; 

    num = 198; 

    Console.WriteLine("Number: " + num); 

    Console.Write("Number in reverse order: "); 

    do { 
      nextdigit = num % 10; 
      Console.Write(nextdigit); 
      num = num / 10; 
    } while(num > 0); 

    Console.WriteLine(); 
  }   
}
Brij
+15  A: 

Something like this?

public int ReverseInt(int num)
{
    int result=0;
    while (num>0) 
    {
       result = result*10 + num%10;
       num /= 10;
    }
    return result;
}

As a hackish one-liner (update: used Benjamin's comment to shorten it):

num.ToString().Reverse().Aggregate(0, (b, x) => 10 * b + x - '0');

A speedier one-and-a-quarter-liner:

public static int ReverseOneLiner(int num)
{
    for (int result=0;; result = result * 10 + num % 10, num /= 10) if(num==0) return result;
    return 42;
}

It's not a one-liner because I had to include return 42;. The C# compiler wouldn't let me compile because it thought that no code path returned a value.

P.S. If you write code like this and a co-worker catches it, you deserve everything he/she does to you. Be warned!

EDIT: I wondered about how much slower the LINQ one-liner is, so I used the following benchmark code:

public static void Bench(Func<int,int> myFunc, int repeat)
{
    var R = new System.Random();
    var sw = System.Diagnostics.Stopwatch.StartNew();
    for (int i = 0; i < repeat; i++)
    {
        var ignore = myFunc(R.Next());
    }
    sw.Stop();
    Console.WriteLine("Operation took {0}ms", sw.ElapsedMilliseconds);
}

Result (10^6 random numbers in positive int32 range):

While loop version:
Operation took 279ms

Linq aggregate:
Operation took 984ms
cfern
Although the one-liner is very inefficient.
KennyTM
Of course, that's why I called it hackish. It's more of a curiosity.
cfern
ToCharArray() is redundant and you could do the char to int conversion from your select in the aggregate as well - saves horizontal space. :) See my sample below for the string-only version.
Benjamin Podszun
@cfern you missed a little check if the number is negative... My teacher back in college would have a field day with this... :-P
Paulo Santos
Oops. That's what happen if you code something within 60 seconds. I wonder how to define the reverse of a negative number. Rev (-1234) = -4321?
cfern
interesting fact - 42 in binary is 101010 ;)
Danail
@Benjamin: thanks for the tip! Intellisense didn't popup any LINQ for a string as char array, even though it's there. Learned something new today :). I've edited the one-liner.
cfern
Probably not a big deal, but shouldn't you use the same numbers for both functions? And maybe generate the numbers before you start the timer?
Svish
Pre-generating the numbers yields a fairer comparison. I've written this bench in a hurry, so I didn't do it as statistically nice as possible. I do think that, in this case, the sheer amount of numbers that go into benchmark averages out the differences from experiment to experiment.
cfern
Thanks cfern...but first method is not working when the number end with 0. For example when I give input 40 this method returning 4.
Pritam Karmakar
That sounds right to me. Because the algorithm I posted calculates with integers, 04 is returned as the number 4. If you wish to keep trailing zeroes, you should work with the number as a string. Something like `return new String(num.ToString().Reverse().ToArray());`, where num is the (integer) input.
cfern
+3  A: 

multiply it by -1? precise your question please...

Stephane
Actually as I mentioned in the question line...I came across this question in a website, where they have published multiple interview question. So I am also confused with the question line.
Pritam Karmakar
+2  A: 

This should do it:

int n = 12345;
int left = n;
int rev = 0;
while(left>0)
{
   r = left % 10;   
   rev = rev * 10 + r;
   left = left / 10;  //left = Math.floor(left / 10); 
}

Console.WriteLine(rev);
jerjer
Thanks so much , but I think this will not work when given number has 0 at end. just like 40
Pritam Karmakar
it will still work on numbers with 0
jerjer
+2  A: 

Yay! A bling way. (No, really. I hope that this is more a "How would I do..." question and not something you really need in production)

public int Reverse(int number) {
  return int.Parse(number.ToString().Reverse().Aggregate("", (s,c) => s+c));
}
Benjamin Podszun
A: 

You can't. Since the computer thinks in hexadecimal in any case, it is necessary for you to tokenise the number into Arabic format, which is semantically identical to the conversion to string.

Alex Brown
@Alex: to be more precise computer works with bits and hexadecimal is an exact multiple (ie: groups of 4 bits for each hexadecimal digit). But it still can do maths however as showed above.
kriss
A: 
    /// <summary>
    /// Reverse a int using its sting representation.
    /// </summary>
    private int ReverseNumber(int value)
    {
        string textValue = value.ToString().TrimStart('-');

        char[] valueChars = textValue.ToCharArray();
        Array.Reverse(valueChars);
        string reversedValue = new string(valueChars);
        int reversedInt = int.Parse(reversedValue);

        if (value < 0)
           reversedInt *= -1;

        return reversedInt;
    }
serhio