7

I have to build a method to add every digit of a string given in parameter and so till there are only 1 digit left, e.g. 1234 = (1+2+3+4) = 10 = (1+0) = 1.

At first, I thought a recursive call or a while loop should be fine. But Is there a smarter way? Using the modulo perhaps?

1234 % 9 = 1 That's seems to work... But no: 9%9 is not equal to 9 but it is to 0.

Is there a way to build this function without recursive/for/ while?

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
Charly Roch
  • 368
  • 1
  • 4
  • 15
  • let me ask you, why swould 9 % 9 be 9 , of cause it is 0 it is the modulo (rest) operator, it tries to put the the 9 as often into the 9 as it can, and the rest will be displayed, so 10 % 4 would be 2 – Marcel Apr 14 '16 at 13:24
  • Is your argument actually a string or a number? Is it's size arbitrary? – Tomasz Lewowski Apr 14 '16 at 13:29
  • modulo divides numbers into classes. 9 and 0 are in the same class and therefore "equal to each other" which means 0=9%9=9. – derlarsschneider Apr 14 '16 at 13:36
  • 2
    What you're looking for is called [digital root](https://en.wikipedia.org/wiki/Digital_root) by the way. And yes, the modulo 9 method works. – biziclop Apr 14 '16 at 13:37
  • @ScriptKiddy I know modulo does not work like that. I was looking for a way to have kind of the same result. – Charly Roch Apr 14 '16 at 13:37
  • Thanks to all of you I have tons of comments and answer. And a related question (sorry for the duplicate I didn't find it) – Charly Roch Apr 14 '16 at 13:39

4 Answers4

7

I have found the simple algorithm somewhere not long a time ago. Actually with it works with %9, however you have to check the case if the modulo of that number is equal 0.

I bet there would exist more ways to reach the result, the simplest code would in Java like this:

int sumAllDigits(int n) {
    return (n%9 == 0 && n!=0) ? 9 : n%9;
}
Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
5
int sumAllDigits(int n) {
    return (n-1)%9 + 1;
}

Works for all n >= 1

MS Srikkanth
  • 3,829
  • 3
  • 19
  • 33
  • it [does work for n = 0 since C99](https://ideone.com/uOKWXh) (because [only since then division is required to round toward zero](https://stackoverflow.com/q/12240228/995714)). To make it work for negative numbers you just need an `abs`. For older C standards you can [use `div()` to achieve the same result](https://stackoverflow.com/a/11726016/995714) – phuclv Jul 03 '18 at 11:18
  • [same to Java](https://stackoverflow.com/q/43953268/995714): https://ideone.com/td6lEo – phuclv Jul 03 '18 at 11:25
4

x%9 actually does work. The only hitch is when you get 0, you don't know if you should have gotten 0 or 9. But you can look back at your original number for that: the only thing that can return 0 is 0. So:

public int digitSum(int input) {
    if ( input == 0 ) {
        return 0;
    }
    int ret = input % 9;
    if ( ret == 0 ) {
        return 9;
    }
    return ret;
}
Teepeemm
  • 4,331
  • 5
  • 35
  • 58
0

Make it a string, then calc sum char by char. If result greater than 9 convert in string and repeat.

public class FakeTest {

    @Test
    public void testCalc() {
        Assert.assertEquals("1234 -> 1", 1, calc(1234));
    }

    private int calc(int value) {
        String svalue = String.valueOf(value);
        int sum = 0;
        for (char c : svalue.toCharArray()) {
            sum += (c - '0');
        }
        return sum > 9 ? calc(sum) : sum;
    }
}
Mikhail Kuchma
  • 583
  • 2
  • 9
  • 1
    We're trying to avoid a loop. And converting a number to a string back to a number is pretty slow. It's better to use `%`. – Teepeemm Apr 14 '16 at 13:34