Problem:
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:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, …
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
Solutions:
1. Python solution:
from math import sqrt limit, current, sum = 4000000, 2, 0 phi3 = ((1+sqrt(5))/2)**3 while sum < limit: sum += current current = round(phi3*current) print (sum)
2. Java solution:
class PE002 { public static void main(String args[]) { long limit = 4000000L, f = 2L, sum = 0L; double phi3 = Math.pow((1 + Math.sqrt(5)) / 2, 3); while(sum < limit) { sum += f; f = Math.round(phi3*f); } System.out.println(sum); } }
Analysis:
The brute-force approach would be to generate terms of the sequence and add terms with even value to get the result.
However, if you observe the Fibonacci sequence, you’ll find that every third term is an even term. In other words, an even term shows up after two terms. So instead of checking each term for divisibility by 2, we can add every third number to the sum. Notice that the series starts with 1 and 2, not 0 and 1.
An amazing fact about the Fibonacci sequence is that the ratio of any term and its previous term is approximately constant (especially for the higher numbers). This constant is the fascinating Golden ratio. So if we divide the term ‘n+1’ by the term ‘n’, we find the result to be equal to the Golden ratio. Using this, given a term n, we can find the term n+1 as T(n+1) = T(n) * phi, where ‘phi’ is the Golden ratio. Now phi has the value (1+sqrt(5))/2, which is 1.6180339887… So the resultant value of T(n+1) has to be rounded off to the nearest integer to get the correct value.
From the formula of T(n+1), we can derive the formula for T(n+2) as T(n+2) = T(n+1) * phi = (T(n) * phi) * phi
Thus, T(n+2) = T(n) * phi2
And T(n+3) = T(n) * phi3
So, the sum of all even terms in the sequence can be calculated by adding T(n), T(n+3), T(n+6), … i.e. T(n), T(n)*phi3, T(n)*phi6, … which is easily achieved by a while loop, with the limit as 4,000,000.
The brute-force program I used for bench-marking:
evenSum, a, b = 0, 1, 2 while a < 4000000: if b % 2 == 0: evenSum += b a, b = b, a+b print(evenSum)
The time taken by the brute-force approach in Python 3.1 in the Ubuntu 10.10 terminal is approximately 0.101734 milliseconds as compared to 0.0601809 milliseconds (59.15% of the time) by the approach explained above.
According to me, this approach can be made more efficient if the floating point calculations can be reduced/replaced.