Arantium Maestum

プログラミング、囲碁、読書の話題

Clojure入門 - Project Eulerを解いてみる 問25

第二十五問

桁数が1000以上の最小のフィボナッチ数を求める。

まずはiterateを使ってフィボナッチ数の数列を定義。

(defn fib-func [[a b]] [b (+ a b)])
(def fib-pairs (iterate fib-func [1 (bigint 1)]))
(def fibs (map first fib-pairs))

bigintをちゃんと使っておく。1000桁も余裕。

桁数がn以上のものをフィルタするための関数を定義。

defn digit-count [n]
  (count (str n)))

(defn n-plus-digits [n]
  (fn [x] (>= (digit-count x) n)))

文字列にして数えるのは正の整数なら問題なし。なのでフィボナッチ数にはお手軽。

StackOverflowから拾ってきた、Predicate関数に合致したindexを返す関数。

(defn indices [pred coll]
   (keep-indexed 
     (fn [index x] (when (pred x) index)) 
     coll))

この関数はすごく便利なのだが、keep-indexedがどうにも気持ち悪く感じてしまう。

ここまでくれば後は組み合わせて終わり。

(->> fibs
     (indices (n-plus-digits 1000))
     first
     inc)

例によってindexが0で始まるのか1で始まるのか、という点でincを使う必要がある。