While the generation and testing approach is easy to understand, it is also not very effective if you want to run it on large numbers. Instead, we can use the inclusion-exclusion principle.
The idea is to first add up too many numbers by considering the multiples of 3, 5, and 7 separately. Then we subtract the ones that we counted twice, i.e. Multiples of 3 * 5, 3 * 7 and 5 * 7. But now we have subtracted too much and we need to add multiples of 3 * 5 * 7 again.
We start by finding the sum of all integers 1..n that are multiples of k . Firstly, we will find out how many of them, m = n / k , are rounded due to integer division. Now we just need to sum the sequence k + 2*k + 3*k + ... + m*k . We define k and get k * (1 + 2 + ... + m) .
This is a well-known arithmetic series, which, as we know, is the sum of k * m * (m + 1)/2 (see triangle number ).
private long n = 9999; private long multiples(long k) { long m = n / k; return k * m * (m + 1) / 2: }
Now we just use the inclusion exception to get the final amount:
long sum = multiples(3) + multiples(5) + multiples(7) - multiples(3*5) - multiples(3*7) - multiples(5*7) + multiples(3*5*7);
This will improve significantly to a larger n than just a loop over all values, but beware of overflows and change to BigInteger if necessary.
hammar
source share