Problem 2
フィボナッチ数列の項は前の2つの項の和である。最初の2項を 1, 2 とすれば、最初の10項は以下の通りである。
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
数列の項が400万を超えない範囲で、偶数の項の総和を求めよ。
Problem 2 - PukiWiki
問題の意味を理解するのにやたら時間を要したというアホすぎる罠。暫く数学的な表現とは無縁の世界に逃避してたからな…
Ruby
sum = 0 fib = [1, 2] while fib.last < 4000000 if fib.last%2 == 0 then sum += fib.last end fib = [fib.last, fib[0]+fib[1]] end puts sum
何の工夫もない。
ここでおもむろにWikipediaでフィボナッチ数を調べてみると、
Fm が偶数となるのは m が 3 の倍数となるときと一致する。
フィボナッチ数 - Wikipedia
これか、これなのか?という事でやってみる。
Wikipedia見たついでにFmはこれで出そう。
Fn の正確な整数値は以下の式で与えられる。
フィボナッチ数 - Wikipedia
def fib(n) ((((1+Math.sqrt(5))/2)**n)/Math.sqrt(5)+0.5).floor end sum = 0 k = 3 while fib(k) < 4000000 sum += fib(k) k += 3 end puts sum
できた。しかしもはやコードを見ただけでは何をやっているのか分からない。
R
sum <- 0 fib <- c(1, 2) while (fib[2] < 4000000) { if(fib[2]%%2 == 0) { sum <- sum + fib[2] } fib <- c(fib[2], fib[1]+fib[2]) } sum
Ruby版の最初のを書き直しただけであった。これは酷い。でもこれどう書き直せばいいかな…
Haskell
fib n = floor ((phi**n)/(sqrt 5) + 0.5) where phi = (1+(sqrt 5))/2 main = print $ sum [x | x <- takeWhile (< 4000000) $ map fib [3,6..]]
う〜ん。変に公式使わないで普通に書いた方が綺麗に書けた気がする。
こうか。
fib = 1:2:zipWith (+) fib (tail fib) main = print $ sum [x| x <- takeWhile (< 4000000) fib, even x]
takeWhile (< 4000000)がめんどいなーと思って[x| x <- fib, x < 4000000 && even x]などと書くと帰ってこなくなる。Haskellよくわかりません。