タッチタイピングプログラム

学生のころはawkで書いてたなぁ。

https://gist.github.com/775780

; touch typing program

(def random (java.util.Random.))

(def keychars "fjdkslaghvmcxzbnrueiwoqpty;,./")

(def *initial-level* 2)

(defn make-problem-word [level]
  (apply str
	 (for [chars (range 0 5)]
	   (nth keychars (.nextInt random level)))))

(defn make-problem-line [level]
  (let [lvl (min level (count keychars))]
    (apply str (interpose " "
			  (for [words (range 0 6)]
			    (make-problem-word lvl))))))

(defn penalty-of-interval [interval]
  (if (<= (* 30 1000) interval) -1 0))

(defn penalty-of-mistakes [mistakes]
  (if (<= 3 mistakes) -1 0))

(defn def-next-level [current-level interval mistakes]
  (let [next-lvl (+ (inc current-level)
		    (penalty-of-interval interval)
		    (penalty-of-mistakes mistakes))]
    (if (> 0 next-lvl) 0 next-lvl))) 

(defn diff-of [problem answer]
  (apply str
	 (map
	  (fn [p a] (if (= p a) \space p))
	  (seq problem) (seq answer))))

(defn count-mistakes [diff]
  (reduce + (map #(if (not= \space %) 1 0) (seq diff))))

(defn main []
  (loop [l *initial-level*]
    (do
      (def problem (make-problem-line l))
      (def start-time (. System currentTimeMillis))
      (println problem)
      (def answer (.readLine *in*))
      (def interval (- (. System currentTimeMillis) start-time))
      (def diff-line (diff-of problem answer))
      (print diff-line)
      (def mistakes (count-mistakes diff-line))
      (def next-level (def-next-level l interval mistakes))
      (println " next-level:" next-level)
      (recur next-level))))