Yes, there are ways to do this that avoid most of the divisions, and are probably faster as well.
Let's start with a simplified version of the problem: add up all the multiples of 3.
Now, you could do a simplified version of what you've written:
int sum = 0;
for (int i=1; i<1000; i++)
if (i % 3 == 0)
sum += i;
...but we know up front that 1 and 2 aren't multiples of three. We can generate all multiples of three by counting by 3's:
int sum = 0;
for (int i=0; i<1000; i += 3)
sum += i;
Obviously enough, we can do the same thing for multiples of 5:
int sum = 0;
for (int i=0; i<1000; i += 5)
sum += i;
But if we do both in succession:
int sum = 0;
for (int i=0; i<1000; i += 3)
sum += i;
for (int i=0; i<1000; i += 5)
sum += i;
...we'll get the wrong answer. The problem now is that if a number is a multiple of both 3 and 5 (e.g., 15) we've counted it twice. There are a few ways we can avoid that. One is to have the second loop add i
to the sum if and only if i
is not a multiple of 3.
for (int i=0; i< 1000; i += 5)
if (i % 3 != 0)
sum += i;
Another is to initially add those, but then add a third loop that generates only the numbers that are multiples of both 3 and 5, and subtracts those from the overall result:
int product = 3 * 5;
for (int i = 0; i < 1000; i += product)
sum -= i;
Since you're (apparently) more interested in learning programming than in learning math, I'll only sketch out the next step. There are ways to avoid doing those loops at all though. What we're really doing is (for two different values of N) summing a series of 1N + 2N + 3N + 4N + ...
Using the distributive property, we can turn that into N * (1 + 2 + 3 + 4 + ...)
. Gauss invented an easy way to sum a series like 1 + 2 + 3 + 4 + ...
, so what we need to do is compute the number of terms of that series we need for each of 3 and 5, compute them, multiply by 3 and 5 respectively, and add together the results. Then do the same for multiples of 15, and subtract that from the result. The number of terms in each series we need will be the upper limit divided by the N for that series--so for multiples of 3, we have 1000/3 terms, and for multiples of 5 we have 1000/5 terms.
So, we can compute the final value as:
3 * gauss_sum(1000/3) + 5 * gauss_sum(1000/5) - 15 * gauss_sum(1000/15)
...and we're left with no loops at all, so we can compute the correct value for any upper limit (up to what fits in an unsigned long long
, anyway) in constant time.
n
but there should be an elegant solution that even a human could do. It is learning these tricks that will help you in later tests were a brute force attack on the problem is not feasible. \$\endgroup\$