Multiples of 3 or 5
Project Euler - Problem 1
If we list all the natural numbers below that are multiples of or , we get and . The sum of these multiples is .
Find the sum of all the multiples of or below .
Solution
First let’s define varibales for the upper bound as well as for the multiples of and .
# upper bound
n = 1000
n -= 1
a = 3
b = 5
I subtract from because I do not want to handle an exclusive upper bound in the functions later described. So from here on we can handle our upper bound as an inclusive one.
Solution 1: Simple iteration
We can use a simple iteration to find the multiples of or by iterating over the numbers from to and checking if the number is divisible by one of the multiples:
def sum_multiples_of(n, *ms):
running_sum = 0
for i in range(1, n + 1):
for m in ms:
if i % m == 0:
running_sum += i
break
return running_sum
result = sum_multiples_of(n, a, b)
Solution 2
The Gaussian Summation Formula is a very useful tool which is going to help us to calculate the sum of our multiples without the need of iterations.
Gaussian Summation
For the gaussian sum we want to find the sum of the first natural numbers:
First, we write the numbers from up to in a row:
Next, right underneath that, we write the same numbers but in reverse order:
Now, if we add the numbers in each column, something interesting happens. Every column adds up to the same total . For example, the first column is , the second is , and so on.
Putting that together, it looks like this:
Since there are columns and each adds up to , the total sum of both rows combined is
Because both rows contain exactly the same numbers, the sum of just one row must be half of that total. So we divide by 2:
And so we arrive at the formula for the sum of the first natural numbers:
Gaussian Summation for multiples of 3 or 5
Now let’s take an example with and consider the multiples of . The numbers look like this:
If we write these numbers in ascending order in one row, and the same numbers in descending order right below, we get:
Each column sums to the same number, which is the first multiple plus the last multiple: , where is the number multiples up to :
In this example, the highest multiple is , so each column sums to:
Since there are columns, the total sum of both rows combined is:
And because the two rows are identical sets of numbers, the sum of just one row (the sum of all multiples of up to ) is half of that:
Here, is the set of multiples of up to .
To find the sum of all multiples of or up to , we use the inclusion-exclusion principle:
Here, is the least common multiple of and , which by subtracting avoids counting common multiples twice. In other words .
Since and are distinct primes, the least common multiple of and is .
Therefore, the sum of all multiples of or up to can be computed with:
def sum_multiples_of(n, m):
c = n // m
return c * (m + c * m) // 2
result = sum_multiples_of(n, a) + sum_multiples_of(n, b) - sum_multiples_of(n, a * b)
print(result) # 233168