Buzzになる数字をn個挙げるをClojureで
このシリーズの一覧はこちら
はじめに
なんか面白そうだったのでClojureで。前回のClojureでFizzBuzzを書いた - No Programming, No Lifeで書いたコードをちょっと改造する感じでできました。
ソース
解説
まずはこれ。
(defn to-fizz-buzz-str [x] [x, (cond (= (mod x 15) 0) "FizzBuzz" (= (mod x 3) 0) "Fizz" (= (mod x 5) 0) "Buzz" :else (str x)) ] )
これは、引数の数値(ここではx)をFizzBuzz文字にマップする関数で、結果はインデックス付きのベクタで返す。
例:
(to-fizz-buzz-str 9) ;=> [9 "Fizz"] (to-fizz-buzz-str 10) ;=> [10 "Buzz"] (to-fizz-buzz-str 15) ;=> [15 "FizzBuzz"] (to-fizz-buzz-str 100002) ;=> [100002 "Fizz"]
で、次にさっき定義した、to-fizz-buzz-str
を利用して、FizzBuzzの無限リストを変数fizz-buzz-list
に束縛。
(def fizz-buzz-list (map to-fizz-buzz-str (iterate inc 1)))
ここで、
(iterate inc 1)は、1から1ずつ増分していく無限シーケンスを生成している部分。
fizz-buzz-list
は無限に続くので、取り扱い注意。利用する際はtake
とかして使うように。
例:
(take 5 fizz-buzz-list) ;=> ([1 "1"] [2 "2"] [3 "Fizz"] [4 "4"] [5 "Buzz"])
to-only-buzz-list
は、引数で受け取ったリストから "Buzz" の部分だけ抜き出す関数です。
(defn to-only-buzz-list [list] (map first (filter #(= (last %) "Buzz") list)))
そしてこれらを組み合わせて、doseq
で出力。
(doseq [x (take 10 (to-only-buzz-list fizz-buzz-list))] (println x))
ここでは、
fizz-buzz-list
(無限のFizzBuzzリスト)を、to-only-buzz-list
に変換- そこから
take
10(シーケンスの先頭から10要素だけ取得)した結果をx
として取得 - それを
println
で出力
しています。
結果:
5 10 20 25 35 40 50 55 65 70
おわりに
Clojure面白くなってきた。
Happy Coding!