Arantium Maestum

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

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

第二十問

100の階乗のすべての桁の数を足し合わせる。

Bigintが存在するのであまり考える必要がない。

まず階乗。

(defn factorial [n]
  (->> n
       range
       (map inc)
       (reduce * (bigint 1))))

最後のステップは、はじめは(map bigint)(apply *)の二つにしていた。 それでも計算は一瞬なのだが、nを1000にしてtime関数を使って比較してみたところ、平均してreduceでやった方が早かった。 bigintを一回しか使わないで済むのがポイントか。

桁の数字をリスト化する関数:

(defn get-digits [n]
  (->> n
       str
       (map int)
       (map #(- % 48))))

文字列化して文字をint化して48引く。(int \0が48なため)

上記二つを組み合わせて、最後にリストの数字を足し合わせる。

(defn factorial-digit-sum [n]
  (->> n
       factorial
       get-digits
       (apply +)))

あとは走らせるだけ。

(factorial-digit-sum 100)