No Programming, No Life

プログラミング関連の話題や雑記

ClojureでFizzBuzzを書いた

このシリーズの一覧はこちら

はじめに

またClojureをちょこちょこいじりはじめています。ということで、凄く初歩的ですがFizzBuzzからやり直しています。
個人的な感想ですが、Clojureはやはり習得が少々難しい気がするので、ステップアップで学べるような記事を今後書いたいけたらなぁとか思っていたりもします。

コード

解説

インデントについて

まず、インデントの付け方ってこんな感じでしょうか? 他のサンプルなどを見よう見まねなのであってるのかわかりません・・・

1-100までのリストを生成
(def one-to-onehandred (map inc (range 100)))

one-to-onehandredという変数に1〜100までのリスト(というかシーケンスになるんだっけ?)に格納しています。(range 100) は 0〜99のリストになるので、(map inc ...) して +1 してあげています。

FizzBuzz文字列にマッピング
(def fizzbuzz-list
  (map
    (fn [x]
       (cond
         (= (mod x 15) 0) "FizzBuzz"
         (= (mod x 3) 0) "Fizz"
         (= (mod x 5) 0) "Buzz"
         :else (str x))) one-to-onehandred))

次に、先ほどのone-to-onehandredをその値を見て、FizzBuzz文字列にマップしてゆくため、無名関数fnを使っています。condで場合分けしています。判定はおなじみの割ったあまりが0になる場合というものです。:elseで、どれにも当てはまらなかった場合を表現していて、単純に(str x)にて文字列にしています。最後に結果のリスト(シーケンス)をfizzbuzz-listという変数に格納します。

出力
(doseq [x fizzbuzz-list] (println x))

そして最後に出力ですが(println ...)という標準出力に出力するという副作用を伴う操作となるので、ここでは(doseq ...)を利用しています。このdo〜は他にもdorunとかdoallとか色々あるのでそのうちまとめたいなと思います。

実行&結果

今回は、以下のようにスクリプトとして実行します。

$ clj fizzbuzz3.clj

結果は

1
2
Fizz
4
Buzz
Fizz
7
(中略)
Fizz
97
98
Fizz
Buzz

のように普通のFizzBuzzの結果となります。

補足

ちなみに僕の環境では clj は以下のようになっています。

CLOJURE=$CLASSPATH:$(brew --cellar)/clojure/1.2.0/clojure.jar

java -cp $CLOJURE clojure.main "$@"

Homebrewがインストールしたものですが、自分でclojure.jarにクラスパスを通して、Javaとしてclojure.mainに実行したいClojureスクリプトファイルを指定して実行することもできます。*1

*1:clojure.mainは引数を指定しなかった場合、REPLとして起動できる。