patternpythonMinor
More efficient solution for Project Euler #2 (sum of Fibonacci numbers under 4 million)
Viewed 0 times
millionfibonaccinumbersmoreefficientprojectunderforeulersum
Problem
I would like to get some feedback on my code. I am starting to program after doing a few online Python courses.
Would you be able to help me by following my track of thinking and then pinpointing where I could be more efficient? (I have seen other answers but they seem to be more complicated than they need to be, albeit shorter; but perhaps that is the point).
Question:
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.
Would you be able to help me by following my track of thinking and then pinpointing where I could be more efficient? (I have seen other answers but they seem to be more complicated than they need to be, albeit shorter; but perhaps that is the point).
Question:
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.
fibValue = 0
valuesList = []
a = 0
b = 1
#create list
while fibValue <= 4000000:
fibValue = a + b
if fibValue % 2 == 0:
valuesList.append(fibValue)
a = b
b = fibValue
print (valuesList) #just so that I can see what my list looks like after fully compiled
print() #added for command line neatness
print() #added for command line neatness
newTot = 0
for i in valuesList:
newTot += i
print (newTot)Solution
A hint that I always offer people with this specific question. Take a look at the first few numbers of the sequence - I have set the even ones in bold:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144...
Can you see a pattern in the spacing? Can you explain (ideally, prove) it?
Given that, can you think of a way to generate even Fibonacci numbers directly, instead of filtering through for them? (Hint: start with (1,2), and try to generate (5,8) in one step, then (21, 34) etc. Do some algebra and figure out how to apply multiple iterations of the generation rule at once.)
Anyway, in terms of doing the actual calculation with the numbers, there are more elegant approaches. Instead of asking Python to build a list directly, we can write a generator:
Notice the use of the
And instead of looping through this sequence to add up the numbers, we can use the built-in
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144...
Can you see a pattern in the spacing? Can you explain (ideally, prove) it?
Given that, can you think of a way to generate even Fibonacci numbers directly, instead of filtering through for them? (Hint: start with (1,2), and try to generate (5,8) in one step, then (21, 34) etc. Do some algebra and figure out how to apply multiple iterations of the generation rule at once.)
Anyway, in terms of doing the actual calculation with the numbers, there are more elegant approaches. Instead of asking Python to build a list directly, we can write a generator:
def even_fibonacci_up_to(n):
a, b = 1, 2
while b <= n:
yield b # since 2 qualifies, after all.
# Now calculate the next value.
# math from the first step goes here when you figure it out!Notice the use of the
yield keyword. This lets us treat our expression even_fibonacci_up_to(4000000) as a special sort of sequence whose elements are generated on-demand. Unlike with ordinary functions which can only return once. :) (Using return inside a generator terminates the whole process of yielding values when it is reached.)And instead of looping through this sequence to add up the numbers, we can use the built-in
sum function:sum(even_fibonacci_up_to(4000000))Code Snippets
def even_fibonacci_up_to(n):
a, b = 1, 2
while b <= n:
yield b # since 2 qualifies, after all.
# Now calculate the next value.
# math from the first step goes here when you figure it out!sum(even_fibonacci_up_to(4000000))Context
StackExchange Code Review Q#39493, answer score: 7
Revisions (0)
No revisions yet.