Project Euler #002 – フィボナッチ数

In: Project Euler

11 11月 2009

Project 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の定義も初めて見たときには、これでちゃんと動くのかがピント来なかった。 これに関する考察はまた別記事にて。

blog comments powered by Disqus
Get Adobe Flash playerPlugin by wpburn.com wordpress themes

About this blog

私 manjilab のポータル的サイトになっております。日々気付いたこと、考えたこと、発表したいものを載せていきます。

Photostream

    Lisp indent 考察Lisp indent 考察Lisp indent 考察Lisp indent 考察Lisp indent 考察Tips to use Clojure(Lisp) with TextMateTips to use Clojure(Lisp) with TextMateTips to use Clojure(Lisp) with TextMate