jrubyのたらい回し関数のエントリみてたらClojureでもやってみたくなった。
Clojure 1.0.0-
user=> (defn tak [x y z]
(if (>= y x)
z
(tak (tak (- x 1) y z) (tak (- y 1) z x) (tak (- z 1) x y))))
#'user/tak
user=> (time (dotimes [_ 100] (tak 24 16 8)))
"Elapsed time: 27580.504 msecs"
nil
ついでにOCamlでも
let rec tak x y z =
if y >= x then z
else tak (tak (x-1) y z) (tak (y-1) z x) (tak (z-1) x y)
;;
for a = 1 to 100 do
ignore(tak 24 16 8)
done
;;
まずはバイトコードで。
$ ocamlc tak.ml -o tak.exe
$ time ./tak.exe
real 0m10.777s
user 0m10.692s
sys 0m0.033s
ネイティブコードにコンパイルすると
$ ocamlopt tak.ml -o tak_opt.exe
$time ./tak_opt.exe
real 0m1.130s
user 0m1.119s
sys 0m0.006s
結構はやい。
そういえばMooseでLispはたらい回し関数はしるくらいまではやっとこうと思いつつ止まってしまっていたのに今気づいた。