Clojure入門 - Project Eulerを解いてみる 問16
第十六問。
21000のすべての桁の数の和を求める。
やはりOverflowが問題になるので、数字を一桁の数のリストで表し、そのリストに対して2倍にするという操作を定義する。あとは'(2)からはじめて1000回繰り返して、足し合わせるだけ。
(require '[clojure.math.numeric-tower :as math]) (defn double [n] (* 2 n)) (defn get-tens [n] (-> n (/ 10) (math/floor))) (defn get-ones [n] (rem n 10))
とりあえずヘルパー関数。
(defn double-list [col] (let [doubled-digits (map double col) ones (map get-ones doubled-digits) tens (map get-tens doubled-digits) tens-shifted (concat (rest tens) '(0))] (if (zero? (first tens)) (map + ones tens-shifted) (cons (first tens) (map + ones tens-shifted)))))
一桁の数のリストに対する、「倍にする」という操作。すべての数を2倍にして、10の位と1の位に分け、ずらして足し合わせる。
(->> '(2) (iterate double-list) (take 1000) (last) (apply +))
あとは使うだけ。
更新: 問十三であやぴーさんにコメント頂いたbigintを使ってしまえば非常に楽:
(->> 2 (bigint) (repeat 1000) (apply *) (str) (map #(Character/digit % 10)) (apply +))