Tally the Digits – Solution

To solve this month’s Exercise, you must create a function that tallies digits in an integer value, what’s known as a digit sum. The key issue is how to peel off individual values in an integer and then total the result.

I can think of two ways to process digits in a value, though more methods are possible.

The first way is to use the modulus operator in the equation n % 10, where n is any integer value. The result of that operation is the final digit in the value. So:

123456789 % 10 = 9

And:

12345678 % 10 = 8

And so on.

To get from 123456789 to 12345678 you divide by 10. For a real number, you’d get:

123456789 / 10 = 12345678.9

But when working with integers, you get:

123456789 / 10 = 12345678

So my first solution for the digit_sum() function is:

int digit_sum(unsigned n)
{
    int total = 0;

    while(n)
    {
        total += n % 10;
        n /= 10;
    }

    /* if the value is over two-digits wide, recurse */
    if(total > 9)
        return(digit_sum(total));

    return(total);
}

The while loop peels through each digit in integer value n. The modulus operator obtains the left-most digit, which is added to the sum in total. Then variable n is divided by 10 and the while loop repeats.

Once all the digits are peeled away, an if statement tests to see whether the result is greater than 9, which means it’s more than a single-digit wide. If so, the function is recursively called in the return statement. Otherwise, the total is returned. Click here to view the full solution.

My second solution was actually the first one I thought of: Convert the integer value into a string, then read the digits from the string, converting each one into a value. Here is the version of the digit_sum() function:

int digit_sum(unsigned n)
{
    char digits[32];
    char *d;
    int total;

    /* convert value to string */
    snprintf(digits,32,"%u",n);

    /* initialize variables */
    d = digits;
    total = 0;

    /* tally all the individual digits */
    while(*d)
    {
            /* subtract '0' from the character to
               retrieve its value */
        total += *d - '0';
        d++;
    }

    /* if the value is over two-digits wide, recurse */
    if(total > 9)
        return(digit_sum(total));

    return(total);
}

As you can see, this solution is more complex, but it still works: The snprintf() statement converts an integer value into a string. The argument 32 ensures that the string generated fits into the digits[] buffer without any overflow. (I’m assuming that an unsigned int value is 32 digits wide.)

Once the value is in a string, the while loop processes each character, left-to-right. (Order doesn’t matter.) The statement total += *d - '0' converts each digit character into a value, which is added to the total variable. Yes, this solution involves pointers, which is scary, but you could do another version that doesn’t use pointers.

As with my first solution, the value of total is compared with 9. If it’s greater, then the digit_sum() function is recursively called in the return statement.

Click here to view the full solution.

I’m certain that other solutions are possible, even if they’re just variations on my two solutions. As long as the digit_sum() function returns the proper value, consider your solution good.

Leave a Reply