Search code examples
cloopsmatharithmetic-expressions

How to find largest sum of divsors of a number between 2 and N?


I have a simple math problem. I want to find a number in the range [2,N] (excluding 1 and N from the divisors) with the largest sum of divisors. For example, for N = 100 the number with the highest sum of divisors between 2 and 100 is 96, which has the sum of all its divisors equal to 155.

I wrote the following program to show me the sum of that number's divisors but couldn't figure out how to get that number itself. How do I find and print that number?

int main(int argc, char const *argv[])
{
    int N,
        sum,
        max=0;

    scanf("%d", &N);

    int i = 0,
        d = 0;
    for(i=2; i<=N; i++)
    {
        sum=0;
        for(d = 2; d < i; d++)
        {
            if(i % d == 0)
            {
                sum += d;
            }
        }

        if(sum > max)
        {
            max = sum;
        }

    }
    printf("%d\n", max);


    return 0;
}

Solution

  • Others have well shown how to save and report the i at which the maximum occurred.

    Yet I wanted to add how OP's approach can be significantly faster: Iterate up to the square root of N rather than N. This way is about square_root(N) times faster. No so important when N is 100, but significant for larger ones.

    #include <stdlib.h>
    #include <stdio.h>
    
    void print_maxsumdiv(int N, int mode) {
      unsigned long long loop_count = 0;
      int sum, max = 0;
      int max_i = 0;
      int i = 0, d = 0;
      for (i = 2; i <= N; i++) {
        sum = 0;
    
        if (mode) {
          // Iterate up to the just under the square root of `i`
          for (d = 2;  d < i/d; d++) {
            loop_count++;
            if (i % d == 0) {
              sum += d + i/d;  // Add both dividers
            }
          }
          if (d == i/d) {  // perfect square
            sum += d;
          }
        }
        else {
          // Iterate up `i`  (OP's original approach)
          for (d = 2;  d < i; d++) {
            loop_count++;
            if (i % d == 0) {
              sum += d;
            }
          }
        }
    
        if (sum > max) {
          max = sum;
          max_i = i;
        }
    
      }
      printf("i:%6d max:%9d (count:%12llu)\n", max_i, max, loop_count);
    }
    
    int main() {
      for (int mode = 0; mode < 2; mode++) {
        print_maxsumdiv(100, mode);
        print_maxsumdiv(10000, mode);
        //print_maxsumdiv(1000000, mode);
      }
      return 0;
    }
    

    Output

    i:    96 max:      155 (count:        4851)
    i:  9240 max:    25319 (count:    49985001)
    i:    96 max:      155 (count:         480)
    i:  9240 max:    25415 (count:      646800)