Search code examples
c++digitslogarithm

easy exercise with difficult solution C++


So, first of all, this SEEMS like one of those exercises that you receive in school when you first start studying programming. Weeeeell it proves to be more than that.

The main exercise is fairly simple, solvable by anyone:

Edit: I got a hold of the original (translated) statement:

Write two implementations for a function that's nonrecursive which has one argument (n = a natural number with 9 digits at most) that returns the number you get by repositioning the first digit of n to the end of the number. As an example, if n is 4273, the function should return 2734. C1) You're allowed to use loops. C2) You're not allowed to use loops.

Aight, first's easy.

    long function(long n)
    {
        long newNumber = 0, p = 1;

        while(n>9)
        {
            newNumber = n%10 * p + newNumber;
            n = n/10;
            p = p*10;
        }

        return newNumber*10+n;
    }

NOW do the same thing without using any kind of loops. No while, for, do while, etc. You don't know how long the number is, might be 3 digits, might me 9. Also the whole work must be done by one function alone.

Now, of course, one simple solution, and a hideous one would be to write something like

    if(n<100)
        return n%10*10+n/10;
    else
        if(n<1000)
            return n%100*10+n/100;
        else
            if...
    ...
    ...
    ...

but that's not the most desirable piece of code. Is there any other clean way of doing this? So far nobody I've asked knew of any other way.

There's another thing. This is supposed to be solvable by a beginner (I came across this while helping a buddy of mine solve one of his exercises) so using some fancy libraries that somehow help that a beginner would never know about shouldn't be a valid solution (yet I'm curious about all the ideas).

Also, I know that you can find out the number of digits a number has by using the formula:

|log(n)| + 1 = ln(n) / ln(10) + 1 which could be used in C++ as follows:

    long function(long n)
    {
            int k; // number of digits of n

            k = (int) (ln(n) / ln(10)) + 1; // applying the formula
            long p = pow(10, k-1);
            return n%p * 10 + n/p;
    }

But I don't remember ever being taught about ln functions in C++ while I was in high school and neither were they. So... Is there any other beginner friendly way of doing this?

List of constraints:

  • one single function
  • no loops
  • receives only 1 parameter in the form of a number (of at most 9 digits)
  • returns the number formed by repositioning its first digit to the end of the number
  • no strings (even though that's a legit solution)

Edit: So in the meanwhile i've been told that the solution the ones that proposed this problem was the one using logarithms..... Which is weird, because their students never used that in c++. My guess is that they fucked up with the statement and that's their "salvation excuse".


Solution

  • Here is one solution that uses std::log10 and std::pow (requires #include <cmath>).

    long func(long in) {
        long base = std::pow(10, (int)std::log10(in));
        long left_most_num = in / base;
        long body = in - left_most_num * base;
        return body * 10 + left_most_num;
    }