いわゆる卍研究所。
In: Project Euler
11 11月 2009Project EulerをClojureでおさらいシリーズ。
続いて Problem 2 に。
日本語訳:
フィボナッチ数列の項はそれより前の2つの項の和で求められる。 先頭の2項を 1, 2 で始めると最初の10項は:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, …
となる。 400万を超えない偶数を値とする項の総和を求めよ。
しかしこういうのってネタバレになるからどこまで書いてていいのか悩むな。 問題によってはコード自体が答えのようなものだから。 まあこの程度の難易度ならまだ問題ないかな。
フィボナッチ数は各要素の値をその都度求めていては計算量が爆発するので 一度計算された項目はちゃんと保持されててほしい。 配列を特異メソッドで拡張するのがよさげです。
以前Rubyで書いたものは:
#!/usr/bin/env ruby def (Fib = [1, 2]).[](n) super || Fib[n] = Fib[n-1] + Fib[n-2] end i = 0 sum = 0 begin i += 1 sum += Fib[i] if Fib[i].even? end while Fib[i] <= 4_000_000 p sum
なんか後半がダサいな。 Fib.next とか使えるように定義しておけばスマートなんだろうね。
Rubyはこの辺にしておいてClojureの方を。
(def fibs (lazy-cat [1 2] (map + fib-seq (rest fibs)))) (reduce + (filter even? (take-while #(< % 4000000) fibs)))
うん、シンプル。
fibsの定義はClojure関連のドキュメントでよく見るやつです。
どちらも数列は [1, 2]ではじめているけど、別に [0,1]ではじめても良いんだよね。 和をとるときに 0 は影響しないし、1 は奇数だからはじかれるから。
このfibsの定義も初めて見たときには、これでちゃんと動くのかがピント来なかった。 これに関する考察はまた別記事にて。
私 manjilab のポータル的サイトになっております。日々気付いたこと、考えたこと、発表したいものを載せていきます。