Today’s challenge is Euler problem #2. I wanted to start with a less intense problem yesterday because I felt that despite its low Project Euler number, that Problem 2 has a lot more interesting things going for it. Here’s the basic 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.
When I first solved this problem as I was just learning Swift, I did so in a fairly obvious way, which is as you see here:
var fib = [Int]() fib += 1 fib += 2 var sum = 2 while fib[fib.count - 1] < 4000000 { fib += fib[fib.count - 2] + fib[fib.count - 1] let lastItem = fib[fib.count - 1] if lastItem < 4000000 { if lastItem % 2 == 0 { sum += lastItem } } } sum
But coming back to it later, I was inspired to completely re-think the problem, to try to, how do I put this?, make it Swiftier, put more Swift in it, Swifticize it.
Here’s what I ended up with:
The later version (I hesitate to say final, even now) uses a generator instead of an array. Only the most recent two terms are stored at any time, ensuring both fixed storage and fixed computation time. It may be a bridge too far in terms of overcomplicating a simple problem but I was pretty pleased with this result.
struct FibGenerator : Generator { typealias Element = Int var i = 0, j = 0 mutating func next() -> Int? { if (i == 0) {i = 1; return 1} if (j == 0) {j = 2; return 2} var sum = i + j; i = j; j = sum return sum } } var fib = FibGenerator() var sum = 0 var current : Int = 0 while current < 4000000 { if current % 2 == 0 {sum += current} current = fib.next()! } sum
As always, please let me know your tweaks, suggestions, and alternatives by Email, Twitter, or comments. Cheers!
3 Comments
From David Grandinetti
http://twitter.com/dbgrandi/status/494914355134480384
From Greg Titus
http://twitter.com/gregtitus/status/494925508379815938
My take, using LazySequence: https://gist.github.com/sparrow79/326a8cc11dfbb1dbb3f7#file-fibonacci-swift