Project Euler: 1-100: Øistein Søvik June 30, 2016
Project Euler: 1-100: Øistein Søvik June 30, 2016
Øistein Søvik
June 30, 2016
1
Contents
Project Euler 1: Multiples of 3 and 5 3
2
Project Euler 1: Multiples of 3 and 5
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum
of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
It is straight forward to iterate over the first 1000 numbers and check for divisibility.
The code above takes on average 12 µs to run. Well under the arbitary 1 s rule. However we can do
better, a small improvement is to allow for different numbers than 3 or 5 and also allow for a customizable
range.
It could seem the above code is quite fast however running numbers_divisible([3, 5], 0, 10**9)
takes about 40 s to run. This is painfully slow, but also expected since the code runs in O(n). As we shall
see we can make the code run in constant time. The first idea is to find out how many numbers are divisible
by 3. In total there are b1000/3c = 333 numbers below 1000 which are multiples of 3. The sum of these can
be found using the sum of the first n numbers
m
X m(m + 1)
i=
i=0
2
However adding these two will give the wrong answer. That is because we are double counting some values?
The numbers we are counting twice are all the numbers divisible by both by 3 and 5. For example 15 is
counted in both sums. Therefore we have to subtract all the numbers divisible by both 5 and 3.
66
66 · (66 + 1)
X
15i = 15 = 99500 (3)
i=0
2
3
Evaluating eq. (1) + (2) - (3). Before we try to code this I want to generalize this idea to find the sum of
an arbitary number k.
blimit/kc blimit/kc low
X X X
ki = i− i
i=low i=0 i=0
k
=∗ (stop + start) ∗ (stop − start + 1), stop = b(limit/kc)
2
We can now write a function that finds the sum of all multiples of k in a range.
def sum_divisible_by_k(k, start, limit):
stop = int((limit-1)/float(k))
return k*(stop+start)*(stop-start+1)/2
def prime_divisors_(divisors):
proper_divisors = []
for div in divisors:
proper_divisors.extend(list(primefac(div)))
return list(set(proper_divisors))
proper_divisors = prime_divisors_(divisors)
total = 0
for divisor in prime_divisors:
total += sum_divisible_by_k(divisor, start, stop)
4
total = 0
for divisor in prime_divisors:
total += sum_divisible_by_k(divisor, start, stop)
This part is the same as before, we are just adding the sum of the multiples of each divisor. The last part
is somewhat tricky and is better understood through an example. Take [2, 7, 3], we first find the numbers
multiplied by each factor. As before we have to remove the double counting. We are double counting all
multiples of 2 · 7, 7 · 3 and 2 · 3. Finding these pairs is done with the combinations module. Sadly removing
all of these multiplies takes away too many numbers. The numbers which are a multiple of 2 · 7 · 3 needs to
be added back into the sum. For the general case we switch between adding and subtracting (this is done
by the k = (−1)i−1 ) until we have gone through the length of the prime divisors.
The running time of this algorithm is O(dk−1 ) where d is the number of divisors. This is also the reason
we take time in the beginning to make sure all the divisors are unique primes.
5
Project Euler 2: Even Fibonacci numbers
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting
with 1 and 2, the first 10 terms will be:
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the
sum of the even-valued terms.
This is one of my favourite problems and as a teaser the solution can be written as
def sum_even_fibonacci(limit):
a, b = 0, 2
while b < limit:
a, b = b, 4 * b + a
return (a + b - 2) / 4
However to understand how this code works we have to go pretty far down the rabbit hole. A warning before
we start: this problem is very easy to solve under 1 s, and any improvements beyond this is purely for the
amusement of the Author.