-1

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;
}
Rami Raghfan
  • 151
  • 12
  • Could you please add a math example of your problem? I don't understand the mathematical task behind it. – Tom Kuschel Dec 06 '18 at 23:13
  • Done, is the example intelligible? – Rami Raghfan Dec 06 '18 at 23:18
  • thanks, I understand: with 96 sum of 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48 – Tom Kuschel Dec 06 '18 at 23:23
  • In [http://www.positiveintegers.org/96](http://www.positiveintegers.org/96) the divisors also include the number 1, so you should try to start at 1 in the second loop of your code to get the sum 156, but nevertheless the 1 doesn't change the maximum of the interval [2,N]. – Tom Kuschel Dec 06 '18 at 23:29
  • sorry! I forgot to mention that the algorithm needs not to include N and 1 as the divisors explicitly – Rami Raghfan Dec 06 '18 at 23:34

3 Answers3

2

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)
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

It should be easy. Just introduce one more variable valueForMax

int N,
    sum,
    max=0,
    valueForMax = 0;

and update it together with max

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

Then you can

printf("best value %d, sum = %d\n", valueForMax, max);
SergGr
  • 23,570
  • 2
  • 30
  • 51
0

When you save max, you just need to save a copy of i in a separate variable.


Here's a working program:

#include <stdio.h>

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

    printf("Enter N: ");
    fflush(stdout);

    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;
            max_i = i;
        }

    }

    printf("MaxSum:%d Index:%d\n", max, max_i);

    return 0;
}

Here's the output:

MaxSum:155 Index:96
Craig Estey
  • 30,627
  • 4
  • 24
  • 48
  • wait, why does max i have the value of -1? – Rami Raghfan Dec 06 '18 at 23:28
  • To prevent a "possibly unitialized value" warning from the compiler. For example, without it, `max_i` would have an uninitialized/unpredictable value if `N` were (e.g.) `1` and the compiler would be able to notice this. So, initializing to _any_ value prevents this warning, but, using `-1` would clearly show that the loop never executed at runtime [since if `max_i = i` _were_ ever executed, it would never be `-1`]. Upon reflection, perhaps `0` would be a better choice. – Craig Estey Dec 07 '18 at 00:01