Hatena::ブログ(Diary)

athosの日記 このページをアンテナに追加 RSSフィード Twitter

2010-01-11

噂の「英単語を覚えるスクリプト」をClojureで

| 噂の「英単語を覚えるスクリプト」をClojureでを含むブックマーク

第1回 Scheme コードバトンのお知らせ - Higepon’s blog - Mona OS and Moshでネタとして挙がっている英単語を覚えるスクリプトClojureで書いてみた、という話。

コード自体はid:higeponさんのScheme(R6RS)版をほぼそのままClojureに移植しただけ。

ソースコード

(追記:ソースコードhttp://gist.github.com/273985 からも見られます。)

(use '[clojure.contrib.duck-streams :only (reader writer)]
     '[clojure.contrib.fcase :only (case)])

(defn make-word-spec
  ([word meaning] [word meaning 0 0])
  ([word meaning ok ng] [word meaning ok ng]))

(defn sort-word-specs [word-specs]
  (sort #(> (- (%1 3) (%1 2))
	    (- (%2 3) (%2 2)))
	word-specs))

(defn file->sexp-list [f]
  (letfn [(rec [r]
	    (lazy-seq
	      (if-let [sexp (read r false false)]
		(cons sexp (rec r))
		(.close r))))]
    (rec (java.io.PushbackReader. (reader f)))))

(defn main-loop [questions results]
  (let [[[word meaning ok ng :as question] & more] questions]
    (letfn [(read-char-ci []
	      (Character/toLowerCase (first (Character/toChars (.read *in*)))))
	    (update-result [ok ng]
	      (cons (make-word-spec word meaning ok ng) results))
	    (p [format & args] (apply printf format args) (flush))]
      (if (nil? question)
	results
	(do (p "%s: \n" word)
	    (read-char-ci)
	    (p "%s: y/n? " meaning)
	    (case (read-char-ci)
	      \y (recur more (update-result (inc ok) ng))
	      \n (recur more (update-result ok (inc ng)))
	      (concat (reverse results) questions)))))))

(defn main [filename]
  (let [word-specs (map #(apply make-word-spec %) (file->sexp-list filename))
	questions (sort-word-specs word-specs)
	results (main-loop questions nil)]
    (with-open [w (writer filename)]
      (binding [*out* w]
	(doseq [result results] (prn (seq result)))))))

(main (first *command-line-args*))

higeponhigepon 2010/01/11 12:00 こんにちは。Closure 版ありがとうございます。sort の %1 や read-char-ci などに感心しました。
Closure おもしろそうですね。
もしご面倒でなければ http://gist.github.com/273431 で fork をクリックしていただいて、コードを貼り付けていただいてもよろしいでしょうか?
そうしていただければ右側の Forks から辿れるようになり、皆さんに Closure 版を見ていただく
機会が増えるかと思います。

athosathos 2010/01/11 13:08 gist で fork しておきました!コードバトン盛り上がるといいですね。

higeponhigepon 2010/01/11 16:09 お手数おかけしました。ありがとうございます!