BrainFuckについて
初めに
この記事は深夜にBrainFuck(またの名をbrainf*ck)を使った結果を見せたいがために作りました。
一応リーダブルコードを遵守しようと思ってはいますが、いかんせん[>.<],-+のみしかないのでコメント頼りです。
オウム返し
入力された文字をそのまま出力します。
, .
入力:3
出力:3
何故かZennはBrainFuck対応でした。
Aを出力
+++++5[>+++++++++++++13<-]
>.
出力:A
メモリを65
にして、65
番目の文字のA
を出力しています。
ASCIIは48
(0)と65
(A)と97
(a)を覚えておくと便利です。
AからZまで出力
+++++5[>+++++5<-]>+<
+++++5[>>+++++++++++++13<<-]
>[>.+<-]
メモリの0番目をカウンタ変数として使っています。
文字は昇順なので、1
足して出力してを繰り返せば全ての文字を出力できます。
カウンタ変数を0番目にしたのは、役割の明確化とメモリ節約のためです。
入力が0以外の時、Aを出力
,
>++++++6[<--------8>-]<
[>+++++5[>+++++++++++++13<-]>.>]
48回引き算をして、0だったら何もしないというプログラムです。
他言語でのif文に等しいです。
みなさんお気づきかと思いますが、コードに色をつけてません。
コードブロックにbrainfuckを指定したら、インクリメントごとに改行を入れてきたので。
繰り上がりのない一桁の足し算
>,>,<<
++++++6[>- - - - - - - -8<-]
>[>+<-]
>.
繰り上がりがないなら、簡単に実装できます。
0番目はカウンタ変数として使っています。
比較および、フラグの立て方
>+<
>>,>,<<<
>>>[<->-]<<<
>>[>+>]<[<]
++++++6[>>>>++++++++8<<<<-]
>>>[>+<-]<<<
>>>>.<<<<
眠くなってきたので適当解説です。
もし0ではないときn番目を1にすれば良いのですが、[>+<]
だと無限ループしてしまうので、工夫しなくてはなりませんでした。
眠くない時にもう少し効率的なフラグの立て方を考えます。
値のコピー
++++++++++10[>+++++++7<-]
>
[>+>+<<-]>>[<<+>>-]<<
<
brainfuckは基本的に0にならないと作業を終了できないので、メモリを3マス用意して、1番目の数を2番目と3番目に移したあと、3番目から1番目に戻しています。
上の方法によって、1番目と2番目が70になります。
インタープリター
今まではウェブ上で動かしていたのですが、少々辛い面もあったのでインタープリターを自作しました。
とりあえずバグは見つかりませんでしたが、なにせ自作ですので不具合が起きるかもしれません。
Iyaがpythonで作ったBrainFuckを実行する環境→
追記:もちろんバグがありました。悲しいです。しかもBrainFuckの動作上絶対に必要な機能がありません。