lazy-sequenceって重要ですね><
http://d.hatena.ne.jp/kencoba/20100405/1270433351
速度が全然違う><
(defn move [a b] ['move a 'to b]) (defn hanoi [a b c n] (if (< n 1) nil (if (= n 1) (list (move a c)) (concat (hanoi a c b (- n 1)) (cons (move a c) (hanoi b a c (- n 1))))))) (defn hanoi-seq [a b c n] ((fn step [a b c n] (lazy-seq (cond (< n 1) nil (= n 1) (list (move a c)) :else (lazy-cat (step a c b (- n 1)) (list (move a c)) (step b a c (- n 1)))))) a b c n)) (defn h [fun n] (fun 'a 'b 'c n)) (defn check [n] (empty? (remove identity (map (fn [i] (= (h hanoi i) (h hanoi-seq i))) (take n (iterate inc 1)))))) (check 15) ; => true (time (do (h hanoi 15) 'end)) ; => "Elapsed time: 5.448703 msecs"end (time (do (h hanoi-seq 15) 'end)) ; => "Elapsed time: 0.054197 msecs"end
まー、単に評価されていないだけなんですけど
(time (do (dorun (h hanoi 15)) 'end)) ; => "Elapsed time: 61.193063 msecs"end (time (do (dorun (h hanoi-seq 15)) 'end)) ; => "Elapsed time: 150.73996 msecs"end