Project Euler - Problem #2

Problem Description

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.

Python Solution 1

This solution creates a function fibon that takes a single argument – maximum. The value of maximum will be 4,000,000 in this example. The function first initializes an iterator (i), a list with two entries (fib), and a variable (n) that will be used to tell Python when to stop the while loop. The while loop creates the next entry in the sequence (fibtemp), makes it a list, and adds it to the fib list. Then it alters the value of n and adds 1 to the iterator.

Next it creates another empty list to hold the even numbers of the sequence (fibeven). The it uses a for loop over the elements of fib to identify whether a particular element is even. If it is even, it adds that element to fibeven. The function then returns the sum of fibeven.

def fibon(maximum):
    i = 2
    fib = [1,2,]
    n=0
    while n < maximum:
        fibtemp=fib[i-2]+fib[i-1]
        fibtemp = [fibtemp]
        fib.extend(fibtemp)
        n = fib[i]
        i = i + 1
    fibeven = []
    for j in fib:
        if j % 2 == 0:
            j = [j]
            fibeven.extend(j)
    return sum(fibeven)

print fibon(4000000)

Python Solution 2

This solution uses a generator function to create the sequence. You can tell it is a generator function because of the yield keyword in it. Then I used NumPy arrays to process the sequence and identify the even numbers. I’ve been using NumPy quite a bit lately, so I wanted to come up with a solution that involved NumPy.

import numpy as np

def fibfun(maxnum):
    x = 0
    y = 1
    while x < maxnum:
        yield x
        x,y = y, x+y

allnum = list(fibfun(4000000))  
npall = np.array(allnum)
npeven = npall[np.where(npall % 2 == 0)]
print np.sum(npeven)