HaskellによるKEMURIインタプリタ
超絶短くてびっくり。西尾泰和のブログ: KEMURIのPythonで書かれたのの約半分の行数。 実装時間の半分以上はビット演算と文字から文字コードに変換する方法を調べるのに費やされた。kemuri関数の中身は割とくだらないことをしているので、たぶんもっと短くスマートに書く方法があるだろうと思う。
-- Kemuri インタプリタ
import Data.Char
import Data.Bits
main = getContents >>= putStr.(\code -> kemuri code [])
kemuri :: String -> [Int] -> String
kemuri ('|':code) stack = km_mkstr stack ++ kemuri code []
kemuri ('^':code) stack = kemuri code $ km_xor stack
kemuri ('~':code) stack = kemuri code $ km_not stack
kemuri ('\'':code) stack = kemuri code $ km_rot stack
kemuri ('"':code) stack = kemuri code $ km_dup stack
kemuri ('`':code) stack = kemuri code $ km_push stack
kemuri (c:code) stack = kemuri code stack
kemuri [] _ = ""
km_xor (x:(y:rest)) = (xor x y):rest
km_not (x:rest) = ((complement x):rest)
km_rot (x:(y:(z:rest))) = (y:z:x:rest)
km_dup (x:rest) = (x:x:rest)
km_push xs = map ord "Hello, world!" ++ xs
km_mkstr xs = map chr xs
__ KEMURIソルバーを作りたかったのだけど、難しかった。幅優先探索と枝刈りをどう実装したらいいのか。 「探索待ち行列に追加」なんてのはリストの破壊的操作ができないから無理だし。リストを順に受け渡していくのか?でも高速な(x:xs)での結合では頭に入れて頭から出してしまうからキューにならないし、 素直にキューにしたらリストの操作だけでかなり重たそう…。
__ Programming:玉手箱:その他。おおー、なんかすごく短い幅優先探索のコードがあった。
__ 捨てるのがもったいないので転載。^'"の3文字からなる文字列を順に生成するリスト。
all_code = foldr1 (++) (iterate f (map (: []) "^'\"")) f xs = [y:x | x <- xs, y <- "^'\""]