Hatena::Groupbugrammer

蟲!虫!蟲!

Esehara Profile Site (by Heroku) / Github / bookable.jp (My Service)
過去の記事一覧はこちら

なにかあったら「えせはら あっと Gmail」まで送って頂ければ幸いです。
株式会社マリーチでは、Pythonやdjango、また自然言語処理を使ったお仕事を探しています

 | 

2011-09-27

[]Clojure入門がてらに「初心者用課題」を解いてみる 03:54

プログラミングスレまとめ in VIP - 初心者用課題

のこと。問題含みながらも、だいたいの書き方はわかったので、解けそうなものを順番に解いてみる。復習もメモしておく。

素数を出せ

(defn prime-number-check [x y]
  (if (= x y) x
              (when-not (zero? (rem x y)) 
              (recur x (inc y)))))

(defn prime-number [x] (remove nil? (map #(prime-number-check % 2) (range 2 x))))

(prime-number 100)

mapでシークエンスを無名関数に渡す。無名関数の場合、引数が一つならば、%でその引数に置き換えてくれる。そうすると、nilと数字の混じったシークエンスが帰ってくるので、removeでnilを外す。

補足 2011.09.29

他の人が添削してくれたようです。感謝。よりClojureらしい素数列 - OGINO Masanori@はてな

ソースを見ていると、(not-any? zero? ,,,,)の使い方がポイントになっている印象。any-not?のソースは(comp not some)で定義されている。これを無名関数に直すと #(not (some %1 %2)) になるようす。someは(some f x)と書け、xのシーケンスに、fの条件にtrueが一つでも存在するならtrueを返し、nilを返す、といったところ。

うるう年を出せ

(defn leap-year-check[x]
  (if 
    (or (and (zero? (rem x 4))
             (> (rem x 100) 0)) 
        (and (zero? (rem x 100)) 
             (zero? (rem x 400))))
    x false))

(defn leap-year [x]
  (remove false? (map leap-year-check (range x))))

(leap-year 2011)

閏年の定義は「百の倍数以外の四の倍数、または四百で割りきれる百の倍数」となっている。なので、そのまま書き写す。Lisp系のソースを見ると、こっちのほうがこなれている。

(defn leap-year-check[x]
  (if 
    (and (zero? (rem x 4)) 
         (or (> (rem x 100) 0) 
             (zero? (rem x 400))))
    x false))

BuzzFizz

(defn buzzfizzcheck [x] (if 
                          (or (zero? (rem x 3)) 
                              (zero? (rem x 5))) (str 
                                                   (when (zero? (rem x 3)) "buzz") 
                                                   (when (zero? (rem x 5)) "fizz") 
                                                  x))
(map buzzfizzcheck (range 100))

そのまま愚直に。strで文字の連結ができるので、3の倍数と5の倍数をチェックして組み合わせるという方法をとってみた。ただ、長さを気にするならそのまま 3の倍数、5の倍数、15の倍数でチェックしてやればいいということにも気がつく。

(defn buzzfizzcheck [x] (cond (= 0 (rem x 15)) "buzzfizz"
                              (= 0 (rem x 3)) "buzz"
                              (= 0 (rem x 5)) "fizz" 
                              :else x))

線形合同法による乱数

かなり力技。evalを使っているところがなんとも、という感じか。もうちょっといい方法があるんだろうけど、自分には思いつかない。

(defn lcgenerator [x a b m]
  (rem (+ (* a x) b) m))

(defn random-lcg-loop [x seed dseq]
  (if (> x 0)
    (recur (dec x) (lcgenerator seed 997 1 65536) (conj dseq (float (/ 1.0 (lcgenerator seed 997 1 65536)))))
    dseq ))

(defn random-mean [x seed]
  (do (println (random-lcg-loop x seed '() ))
      (println "the mean is " (/ (eval (into (random-lcg-loop x seed '() ) '(+) )) x ))))

(random-mean 100 200)

 conjは元シークエンスに追加するシークエンスを入れるという命令。

 合計を出すためには、発生した乱数をなんらかの形で保存しなきゃいけないだろうなというつもりで書く。random-lcg-loopを二回呼び出しているのがはっきりいって無駄。本来なら無名関数でラップしてやって、一個の引数で二つに適用するのが望ましいのかな。リソースの節約的には。

数当てゲーム

(import 'java.util.Random)
(defn gamesystem [ans]
  (when-not(#(cond (> %1 %2) (do (println "It is Small !!")
                             false)
                 (< %1 %2) (do (println "It is Big !!")
                               false)
                 (= %1 %2) (do (println "Year !! Yes !!")
                               true))
           ans (Integer. (read-line))) (recur ans)))

(defn game-start [x] (do (println "Game start!!")
                         (println "Max number is" x "!! OK ?")
                         (gamesystem (.nextInt (new Random) x))))

(game-start 100)

 せっかくなので、JavaのRandom乱数を使用して記述。愚直にread-lineで比較してしまうと、そのつど入力を迫られてしまうので、一度無名関数でラップする。無名関数でラップしたあとに、read-lineを引数としてわたしてやれば、入力は一度で、複数の判定が可能になる。

 read-lineの中身はString型なので、Integer型にしてやらないといけない。当然、解答のNumberも同じものを渡さなきゃいけないので、recurで再帰させる。基本的にread-line自体は、次のゲームに影響が出ないので、捨てる。さすがに手続き型みたいにどこかの変数に保存するのもあまりよろしくないので、game-startで初期化してgamesystemに渡してやる。

FelipeFelipe2012/06/10 07:43Great cmoomn sense here. Wish I'd thought of that.

znoxjjxeulvznoxjjxeulv2012/06/10 20:43HkDAs9 <a href="http://dxdlitefthko.com/">dxdlitefthko</a>

elwdfsldelwdfsld2012/06/11 11:095SBXeN , [url=http://wivsbufoolwv.com/]wivsbufoolwv[/url], [link=http://xdugmyrhknkj.com/]xdugmyrhknkj[/link], http://aakczdbarkuc.com/

fljodnnwjfljodnnwj2012/06/13 17:19Vgpftf , [url=http://rezupnojoxxz.com/]rezupnojoxxz[/url], [link=http://ykzbtkkkwqgt.com/]ykzbtkkkwqgt[/link], http://stfapcondhdn.com/

 |