8
\$\begingroup\$

Today I've found /r/dailyprogrammer and I've solved an easy challenge. I'm new to coding and I'm not sure if this is good way to solve this kind of problems. Could you, please, give me some hints? How to make my code more clear and readable? Thanks!

Challange description:

A number is input in computer then a new no should get printed by adding one to each of its digit. If you encounter a 9, insert a 10 (don't carry over, just shift things around).

For example, 998 becomes 10109.

Bonus

This challenge is trivial to do if you map it to a string to iterate over the input, operate, and then cast it back. Instead, try doing it without casting it as a string at any point, keep it numeric (int, float if you need it) only.

private static int Challange(int number)
        {
            int digits = (int)Math.Log10(number); //this is number of digits -1 
            int result = 0;
            for (int i=0; i <= digits; i++)
            {
                int tens = (int)(Math.Pow(10, digits - i));
                int currentDigit = ((number / tens) % 10);

                if (currentDigit == 9) result *= 10;
                result += (currentDigit + 1) * tens;
            }
            return result;
        }
\$\endgroup\$
  • 2
    \$\begingroup\$ Is 0 a valid input? If so, what should the result be? \$\endgroup\$ – YawarRaza7349 Feb 27 at 20:48
3
\$\begingroup\$

It's a matter of taste but I find a recursive solution to be reasonably readable :

private static int IncrementDigits(int number){
    if (number == 0){
        return 0;
    }

    int lastDigit = number % 10;
    int firstDigits = number / 10;

    if (lastDigit == 9){
        return 10 + 100 * IncrementDigits(firstDigits);
    } else {
        return lastDigit + 1 + 10 * IncrementDigits(firstDigits);
    }
}

Note that it only works for number > 0.

Here's a working example: https://dotnetfiddle.net/xUKs6M

\$\endgroup\$
  • 2
    \$\begingroup\$ You could use System.Math.DivRem to do the division and modulo operations (on .Net Core this would be faster, the .Net Framework implementation does the naïve thing of doing the division twice) \$\endgroup\$ – user190892 Feb 27 at 20:45
  • \$\begingroup\$ @mistertribs: Thanks. I wanted to stay close enough to OP's answer. I don't really like the output argument in Math.DivRem, to be honest. \$\endgroup\$ – Eric Duminil Feb 27 at 21:04
8
\$\begingroup\$

It works, but it's a bit tricky to follow the logic and work out why. If you work from the other end then you can avoid the Log and Pow and shifting the partial result, and I find that easier to read.


Challange is not a descriptive name. What does the method do? IncrementDigits might be a better name, for example.

\$\endgroup\$
2
\$\begingroup\$

Computing powers repeatedly and log are not cheap operations. You could substitute them with cheaper alternatives:

  • Instead of computing powers of tens, you could start with 1 and multiply in the loop steps.
  • Instead of computing the number of digits and using a counting loop, you could divide by 10 until reaching 0.

Something like this:

if (number == 0) {
  return 1;
}

int work = number;

int tens = 1;
int result = 0;
while (work > 0) {
  int digit = work % 10;
  work /= 10;

  result += tens * (digit + 1);
  tens *= 10;
  if (digit == 9) {
    tens *= 10;
  }
}
return result;
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.