Search code examples
cloopssumlong-integer

how to find out whether a number is the sum of a number and its digit's sum


long integers t and x are input. 1 ≤ t ≤ 100 000 and 1 ≤ x ≤ 1 000 000.

first, we take t from input and in the next t lines, we take x in each line. if there's any number a such that x = a + sum-of-digits(a), print Yes. if not, print No.

e.g: input :

2
97
119

output:

No
Yes

in this example, t = 2. so, we're given 2 numbers in the next lines. for 97, there's no number a such that 97 = a + sum-of-digits(a). therefore, the output is No. but for 119, 119 = 109 + 1 + 0 + 9 so 109 is a matching value of a and the output is Yes.

Here's my code but it doesn't run properly and I don't know why. can anyone figure out why it doesn't? or another idea for solving this question?

#include <stdio.h>

int main()
{
    long int t, x;
    scanf("%ld ", &t);
    for (int i = 0; i < t; i++)
    {
        scanf("%ld ", &x);
        unsigned int n = 1;
        while (n < 1000000)
        {
            long int r, count = 0, sum = 0;
            r = n;
            while (r > 0)
            {
                n = r % 10;
                sum += n;
                r /= 10;
                count++;
            }
            // sum = sum of digits of n
            if (x == (sum + x))
            {
                printf("Yes\n");
                break;
            }
        
            n++;
        }
        printf("No\n");
    }

    return 0;
}

Solution

  • There are 3 bugs in your code.

    And as @chqrlie mentions in a comment: i and n should have type long int

    So that the types are consistent.

    See comments and fixes below:

    #include <stdio.h>
    int main()
    {
        long int t, x;
        scanf("%ld ", &t);
        for (long int i = 0; i < t; i++)  // Type change
        {
            scanf("%ld ", &x);
            long int n = 1;       // Type change
            while (n < 1000000)
            {
                long int r, count = 0, sum = 0;
                r = n;
                while (r > 0)
                {
                    // n = r % 10; Bug: Overwriting n will mess up the loop
                    // sum += n;
                    long int tmp = r % 10; // Fix: Use another variable
                    sum += tmp;            //      or directly do sum += r % 10
    
                    r /= 10;
                    count++;
                }
                // sum = sum of digits of n
                // if (x == (sum + x))     Bug: Simple typo
                if (x == (sum + n))    //  Fix: Use n
                {
                    printf("Yes\n");
                    break;
                }
            
                n++;
            }
            // printf("No\n");   Bug: Will always print after the while
            if (n == 1000000) printf("No\n"); // Fix: Only print when the while loop
                                              //      reached the maximum value for n
        }
    
        return 0;
    }
    

    Besides the bugs the variable count isn't used and there are performance problems, i.e. the while loop doesn't need to run to more than x-1. So try:

    #include <stdio.h>
    int main()
    {
        long int t, x;
        scanf("%ld ", &t);
        for (long int i = 0; i < t; i++)
        {
            scanf("%ld ", &x);
            long int n = 1;
            while (n < x)         // Performance improvement
            {
                long int r, sum = 0;
                r = n;
                while (r > 0)
                {
                    sum += r % 10
                    r /= 10;
                }
                if (x == (sum + n))
                {
                    printf("Yes\n");
                    break;
                }
            
                n++;
            }
            if (n == x) printf("No\n");   // Notice this change
        }
    
        return 0;
    }
    

    And you can do even better by noticing that the sum of digits can't be more than 54. The highest x value is 1000000 so 999999 will generate the highest possible digit sum, i.e. 6 * 9 = 54. In other words, for values of x above 54, you only need to check the 54 numbers before x. Like:

    #include <stdio.h>
    int main()
    {
        long int t, x;
        scanf("%ld ", &t);
        for (long int = 0; i < t; i++)
        {
            scanf("%ld ", &x);
            long int n = (x > 54) ? x - 54 : 1;  // Select start value
            while (n < x)
            {
                long int r, sum = 0;
                r = n;
                while (r > 0)
                {
                    sum += r % 10
                    r /= 10;
                }
                if (x == (sum + n))
                {
                    printf("Yes\n");
                    break;
                }
            
                n++;
            }
            if (n == x) printf("No\n");
        }
    
        return 0;
    }