4

I was solving a Project Euler problem that goes as follows:

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

So I used this script to print the Fibonacci sequence up to four million:

a = 0
b = 1
while b < 4000000:
    print b
    a, b = b, a+b

Obviously, I could run this and just manually add the even values, but I would feel like I'm cheating.

Technically, I guess I'm asking two questions:

  1. How could I pick out the evens?
  2. How could I add those evens without actually assigning them to a variable?

Oh, and I'm sure its extremely evident, but I'm very new to...well, programming in general and I can get lost in experts' verbosity easily. Thanks in advance!

johnsyweb
  • 136,902
  • 23
  • 188
  • 247
Grant
  • 891
  • 1
  • 9
  • 15

3 Answers3

6

If you're averse to variable assignments, you might enjoy a functional approach:

>>> from itertools import takewhile, ifilter

>>> def fib():
        a, b = 0, 1
        while True:
            yield a
            a, b = b, a+b

>>> def is_even(x):
        return x % 2 == 0

>>> sum(ifilter(is_even, (takewhile(lambda x: x<4000000, fib()))))
4613732
Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
  • Use `return not (x % 2)` instead of `return x %2 == 0`: it is more pythonic and faster. – gecco Dec 24 '11 at 09:17
  • 2
    @gecco `return not (x % 2)` exploits the fact that a 0 is treated like `False` and makes the condition implicit. I don't see how this could possibly be considered more pythonic. I doubt that it would make a difference on other implementation than CPython as well. – DasIch Dec 24 '11 at 20:07
2

Ah, Project Euler!

This is more a math question than a programming question, though.

On the programming side, simply add an accumulator. You can test for evenness by using the modulo operator %, which returns the integer remainder after dividing the left operand by the right operand.

a, b = 0, 1
evens = 0
while b < 4000000:
    if not b%2:
        evens += b
    a, b = b, a+b

Once you have the answer, the Project Euler PDF and forums will fill you in on the mathy part of this problem and really answer your questions. There are ways to avoid having to calculate every Fibonacci number and having to test for evenness, but these require exploiting specific mathematical properties of the Fibonacci sequence.

Francis Avila
  • 31,233
  • 6
  • 58
  • 96
1

How could I pick out the evens?

Even numbers are the ones that leave a remainder of zero when you divide them by 2 (in integers). In Python, we get 'the remainder after dividing as an integer' with the % operator.

However, there's another neat trick you can do here. The even Fibonacci numbers are every third number in the sequence, and if you can rigorously prove why, then you'll be close to getting the formula needed to just generate the sequence of even Fibonacci numbers directly.

How could I add those evens without actually assigning them to a variable?

What's wrong with assigning them to a variable? Just set up another one for the running count.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
  • I didn't figure out the trick you spoke of, but your answer was simplistic. And it led me to find an alternate route. I just added a short 'if' statement to add the even values up. Thanks! – Grant Dec 24 '11 at 22:45
  • I'm actually not so sure about my assertion about the trick any more. >_ – Karl Knechtel Dec 24 '11 at 23:07