Problem 2 — Even Fibonacci Numbers

solved Fri, 3 Jul 2015, 14:05 · level 0 · difficulty 1% projecteuler.net github

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, \dots$$

By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.


Problem Analysis

The Fibonacci sequence is defined by the recurrence relation F(n) = F(n-1) + F(n-2). Here the sequence is seeded with 1 and 2, and the task is to sum every even-valued term that does not exceed four million. The naive approach generates every Fibonacci number and tests each for evenness, but a structural observation about parity removes the test entirely. Writing out the parity of the terms - 1 (odd), 2 (even), 3 (odd), 5 (odd), 8 (even), 13 (odd), 21 (odd), 34 (even) - shows that every third term is even. This follows directly from the addition rule on parity: odd+even=odd, even+odd=odd, odd+odd=even, so the pattern repeats with period three forever.

Knowing the even terms recur every three steps, I can derive a recurrence that steps directly from one even Fibonacci number to the next, skipping the two odd ones between. If E(k) is the k-th even Fibonacci number, then E(k+1) = 4*E(k) + E(k-1), which is verifiable by expanding the standard recurrence three times. The payoff is that I need only two integer state variables and a single multiply-add per step, with no divisibility test. Because Fibonacci numbers grow exponentially - each term is roughly 1.618 times the previous, the golden ratio - the count of terms below any limit L is O(log L). The algorithm therefore runs in logarithmic time and O(1) space, finishing in a handful of iterations even for a limit of four million.

Solution Approach

Direct Even-Fibonacci Recurrence (Python and C)

Both files implement the same algorithm. I keep two consecutive even Fibonacci numbers, even_fib_a and even_fib_b, seeded with 2 and 8 - the first two even Fibonacci terms. Each step accumulates even_fib_a into the running total, then advances the pair with next = 4 * even_fib_b + even_fib_a, shifting even_fib_a = even_fib_b and even_fib_b = next. The loop exits as soon as even_fib_a reaches or exceeds the limit, so the limit is never included - the "does not exceed" bound is applied strictly before accumulation.

I chose the seed (2, 8) rather than deriving it from first principles because both values are easy to confirm by inspection against the listed sequence, and a recurrence is only as correct as its initial conditions. A wrong seed such as (0, 2) would silently corrupt every later term, since 0 is not part of the stated sequence.

The Python version wraps the iteration in a private generator _even_fibonacci_numbers and feeds it to sum(), cleanly separating sequence generation from aggregation. The C version is a plain while loop accumulating into a long long to guard against overflow. Both delegate argument parsing to the runner framework's parse_int helper, so the remaining difference is purely idiomatic: a lazy generator feeding sum() in Python versus an explicit accumulation loop in C. Both produce 4613732 for the four-million case; the recorded averages are about 0.42 microseconds in C and 1.6 microseconds in Python.

workbench

Test cases

categoryinputanswer
dev max_limit = 10 10
dev max_limit = 100 44
main max_limit = 4000000 4613732

Results

solutioncategoryanswerverdict avg seconds cavg seconds py
p0002_s0 dev 10 correct 0.000001 (126) 0.000001 (126)
p0002_s0 dev 44 correct 0.000001 (126) 0.000001 (126)
p0002_s0 main 4613732 correct 0.000001 (126) 0.000002 (126)

Files

Tags & blogs

Blogs