前回に続いてCarpその2。 hello worldは書いたので、続いてfizz bazzを書く。
(defn fizz-buzz [n] (do (if (and (= (mod n 3) 0) (= (mod n 5) 0)) (IO.print "fizzbuzz ") (if (= (mod n 5) 0) (IO.print "buzz ") (if (= (mod n 3) 0) (IO.print "fizz ") (do (IO.print &(Int.str n)) (IO.print " "))))) (if (< n 20) (fizz-buzz (+ n 1)) 0))) (defn main [] (fizz-buzz 1))
carp -x fizz-buzz.carp
1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz 16 17 fizz 19 buzz
if式の中にprintが沢山あるのでまとめたいのだが、うまく動かず。
(defn fizz-bazz [n] (do (IO.print (if (and (= (mod n 3) 0) (= (mod n 5) 0)) "fizzbuzz" (if (= (mod n 5) 0) "buzz" (if (= (mod n 3) 0) "fizz" &(Int.str n))))) (if (< n 20) (do (IO.print " ") (fizz-bazz (+ n 1))) (do (IO.println "") 0)))) (defn main [] (fizz-bazz 1))
carp -x fizz-buzz2.carp
fizz buzz fizz fizz buzz fizz fizzbuzz fizz buzz
型エラーも出ずに実行できるが、数字が出力されない。 何かやり方間違ってるんだろうがよく分からん。。。
出力コードの対象部分を見ると
} else { String _59 = Int_str(n); String* _60 = &_59; // ref String* _61 = _60; String_delete(_59); _62 = _61; }
参照を渡しているが、参照先の文字列がスコープから外れるから削除されているように見える。
(defn fizz-bazz [n] (do (IO.print &(if (and (= (mod n 3) 0) (= (mod n 5) 0)) @"fizzbuzz" (if (= (mod n 5) 0) @"buzz" (if (= (mod n 3) 0) @"fizz" (Int.str n))))) (if (< n 20) (do (IO.print " ") (fizz-bazz (+ n 1))) (do (IO.println "") 0)))) (defn main [] (fizz-bazz 1))
carp -x fizz-buzz3.carp
1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz 16 17 fizz 19 buzz
これで正しく動いてるように見えるが、文字列リテラルをわざわざコピーするもんなのか?
最後にループで書いてみる。
(defn main [] (do (let [n 1] (while (<= n 20) (do (IO.print &(if (and (= (mod n 3) 0) (= (mod n 5) 0)) @"fizzbuzz" (if (= (mod n 5) 0) @"buzz" (if (= (mod n 3) 0) @"fizz" (Int.str n))))) (IO.print (if (< n 20) " " "\n")) (set! n (inc n))))) 0))
carp -x fizz-buzz4.carp
1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz 16 17 fizz 19 buzz
複数の式を列挙出来るのはdoだけで、defnのbodyですらダメなのか。 中々凄いな。。。