続brainf*ck
CLで無駄に実装3つ書いた。
- 前のポストのコードの修正版
- ジャンプ処理を統合
- ごく普通のインタプリタ実装
- ふつう
- リーダーマクロ
- #^から^までの文字列をBrainf*ckコードとして処理して、テープの最終状態とポインタ位置を多値で返す
- テープの長さは100固定で自動拡張しないが、#n^...^と書くとテープの長さがnになる
- xyzzyだと一部のコードで結果がおかしくなる
リーダーマクロの例
* #^++++++++[>++++++++<-]>+.^ A #(0 65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) 1 * (multiple-value-list #4^+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.------------.<++++++++.--------.+++.------.--------.>+.^) Hello, world! (#(0 72 100 33) 3)
Brainf*ckスレに貼られていた素数探索のコードで速度とか比較してみる。
CL処理系はsbcl 1.0.22を使用。
ネタ再帰版
Evaluation took: 31.610 seconds of real time 31.453125 seconds of total run time (31.390625 user, 0.062500 system) [ Run times consist of 0.422 seconds GC time, and 31.032 seconds non-GC time. ] 99.50% CPU 58,924,553,863 processor cycles 2,612,290,480 bytes consed
普通の
Evaluation took: 6.234 seconds of real time 6.218750 seconds of total run time (6.218750 user, 0.000000 system) 99.76% CPU 11,625,169,955 processor cycles 136,944 bytes consed
リーダーマクロ
Evaluation took: 0.453 seconds of real time 0.453125 seconds of total run time (0.453125 user, 0.000000 system) 100.00% CPU 821,685,004 processor cycles 132,688 bytes consed
ちなみにリーダーマクロの展開結果はこんな感じ。
(let ((tape (make-array 100)) (pos 0)) (incf pos 1) (incf (aref tape pos) 4) (loop while (< 0 (aref tape pos)) do (decf pos 1) (incf (aref tape pos) 8) (incf pos 1) (decf (aref tape pos) 1)) (incf pos 1) (incf (aref tape pos) 7) (loop while (< 0 (aref tape pos)) do (decf pos 1) (incf (aref tape pos) 8) (incf pos 1) (decf (aref tape pos) 1)) (decf pos 1) (incf (aref tape pos) 1) (incf pos 1) (incf (aref tape pos) 9) (incf pos 2) (incf (aref tape pos) 10) (loop while (< 0 (aref tape pos)) do (decf pos 1) (incf (aref tape pos) 10) (incf pos 1) (decf (aref tape pos) 1)) (decf pos 1) (decf (aref tape pos) 2) (loop while (< 0 (aref tape pos)) do (incf pos 1) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)) (decf pos 1) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1) (incf pos 1) (incf (aref tape pos) 1) (incf pos 1) (incf (aref tape pos) 1) (decf pos 2)) (incf pos 2) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1) (decf pos 2) (incf (aref tape pos) 1) (incf pos 2)) (decf pos 1) (decf (aref tape pos) 1) (loop while (< 0 (aref tape pos)) do (incf pos 1) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)) (decf pos 2) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1) (incf pos 2) (incf (aref tape pos) 1) (incf pos 1) (incf (aref tape pos) 1) (decf pos 3)) (incf pos 3) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1) (decf pos 3) (incf (aref tape pos) 1) (incf pos 3)) (decf pos 1) (incf (aref tape pos) 1) (loop while (< 0 (aref tape pos)) do (incf pos 2) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)) (incf pos 1) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)) (decf pos 2) (loop while (< 0 (aref tape pos)) do (incf pos 1) (incf (aref tape pos) 1) (incf pos 1) (incf (aref tape pos) 1) (decf pos 2) (decf (aref tape pos) 1)) (incf pos 2) (loop while (< 0 (aref tape pos)) do (decf pos 2) (incf (aref tape pos) 1) (incf pos 2) (decf (aref tape pos) 1)) (decf pos 1) (incf pos 1) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)) (incf (aref tape pos) 1) (decf pos 1) (loop while (< 0 (aref tape pos)) do (incf pos 1) (decf (aref tape pos) 1) (decf pos 1) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1))) (incf pos 1) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1) (decf pos 4) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1) (incf pos 2) (incf (aref tape pos) 1) (incf pos 2) (incf (aref tape pos) 1) (decf pos 4)) (incf pos 4) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1) (decf pos 4) (incf (aref tape pos) 1) (incf pos 4)) (decf pos 2) (incf (aref tape pos) 1) (incf pos 2)) (decf pos 2) (decf (aref tape pos) 1) (decf pos 1) (decf (aref tape pos) 1)) (incf pos 1) (incf pos 1) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)) (incf (aref tape pos) 1) (decf pos 1) (loop while (< 0 (aref tape pos)) do (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)) (incf pos 1) (decf (aref tape pos) 1) (decf pos 1)) (incf pos 1) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1) (decf pos 1) (incf pos 2) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)) (incf (aref tape pos) 1) (decf pos 4) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)) (incf (aref tape pos) 1) (incf pos 3)) (decf pos 3) (decf (aref tape pos) 1)) (incf pos 4) (incf pos 1) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)) (incf (aref tape pos) 1) (decf pos 1) (loop while (< 0 (aref tape pos)) do (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)) (incf pos 1) (decf (aref tape pos) 1) (decf pos 1)) (incf pos 1) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1) (decf pos 8) (princ (code-char (aref tape pos))) (incf pos 3) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)) (incf (aref tape pos) 6) (loop while (< 0 (aref tape pos)) do (decf pos 2) (incf (aref tape pos) 8) (incf pos 2) (decf (aref tape pos) 1)) (decf pos 2) (princ (code-char (aref tape pos))) (incf pos 2) (incf (aref tape pos) 6) (loop while (< 0 (aref tape pos)) do (decf pos 2) (decf (aref tape pos) 8) (incf pos 2) (decf (aref tape pos) 1)) (decf pos 4) (princ (code-char (aref tape pos))) (incf pos 9)) (decf pos 6) (decf (aref tape pos) 1) (incf pos 2) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)) (decf pos 3) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1) (incf pos 2) (incf (aref tape pos) 1) (incf pos 1) (incf (aref tape pos) 1) (decf pos 3)) (incf pos 3) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1) (decf pos 3) (incf (aref tape pos) 1) (incf pos 3)) (decf pos 1) (incf pos 1) (incf (aref tape pos) 1) (decf pos 1) (loop while (< 0 (aref tape pos)) do (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1)) (incf pos 1) (decf (aref tape pos) 1) (decf pos 3) (decf (aref tape pos) 1) (incf pos 2)) (incf pos 1) (loop while (< 0 (aref tape pos)) do (decf (aref tape pos) 1) (decf pos 3) (incf (aref tape pos) 9) (decf pos 1) (decf (aref tape pos) 1) (incf pos 4)) (decf pos 2)) (values tape pos))
おまけのbookmarklet用Javascript。スレに投下したら添削、じゃなくて一方的に100字ほど削ってもらえた。