レス数が1スレッドの最大レス数(1000件)を超えています。残念ながら投稿することができません。
おちゃめくらぶ掲示板
-
Brainfuckで四則演算
先日プチコンでBrainfuckインタープリタである「Petit Brainfuck」を作ったのだけど
それを使って加減乗除を行うコードを書いてみたにょ。
ちなみに使用環境はPetit Brainfuck(改造点で書いた「入力命令」「多重ループ」「ブレーク
ポイント」を追加したもの)+PETIT EDITOR+ラベルスタートの3つのプログラムにょ。
これによって、プチコンのみで快適にBrainfuckのコードが書けるにょ。
しかも、全部合わせても2KB足らずと非常にコンパクトにょ。
では、まずはどのような仕様にするかを考えるにょ。
入力命令「,」を用いてキーボードから2つの数を入力してそれをポインタ0、1に入れて
両者を加算してポインタ2に入れるというものにしようと思うにょ。(入力命令はPetit
Brainfuckではデフォ状態ではオプション扱いになっているので動作のためには追加は必須)
具体的に書けば加算の場合はキーボードから[4][2]を入れたらポインタの値は[4][2][6]に
なるというものにょ。
終わった時に操作しているポインタにカーソルを合わせておけばどれが答えになるかも
分かりやすくなるにょ。
本来ならば出力命令を使って「4+2=6」という感じのものを表示したいところだけど答えが
2桁になった時に非常に難易度が高くなるにょ。
というのも仮に答えが35になった場合に「35」という文字を出力するためには10の位と
1の位に分けないといけないからにょ。
つまり、「35÷10=3…5」というように除算の商と余りを求めるコードを書く必要性がある
ためにょ。
それは、Brainfuck初心者の私にとってはかなりハードルが高いし、Petit Brainfuckでは
上限が255文字となっているためそんな複雑なコードは書けないため今回は出力命令は使用
しないことにしたにょ。
というわけでまずは、加算のコードにょ。(79文字)
,>,>++++++++[<------<------>>-]<<[>>+>+<<<-]>>>[<<<+>>>-]<<[>>+<<-]>>[<+<+>>-]<
PCで動作させるならば「Brainfuckインタープリタ」はぐぐれば多数見つかるのでその中から
ポインタ(メモリ)の値が分かるものを使ってコピペしてから実行するとこのコードが
どのようなものかが分かるにょ。
まずは、ポインタ0、1にテンキー(0〜9)で入力した文字の値を入れる必要があるけど
「1」は文字コード49であるためポインタ0、1の指す値から48ほどマイナスしているにょ。
次にポインタ0の値をポインタ2にコピー(ポインタ0の値をポインタ2、ポインタ3に移動した
後にポインタ3の値をポインタ0に移動)、ポインタ1の値をポインタ3に移動した後に
ポインタ3の値をポインタ1、2に移動・・・これで完了にょ。
例えば、5、4と入力すれば[5][4][9]となってカーソルは[9]の場所にあり5+4=9が計算できた
ことが分かるにょ。
ポインタ0、1の値を破壊していいのならば大幅に短いコードは書けるけど最初に書いた仕様
通りだとこれが一番理解しやすいのではないかと思うにょ。(それでも時間をかけて考えれば
これよりもかなり短縮できそうだけど)
ちなみにポインタ0、ポインタ1の値を破壊してもいいならば同じものが35文字に短縮可能にょ。
,>,[<+>-]++++++++[<------------>-]<
次は減算のコードにょ。(79文字)
,>,>++++++++[<------<------>>-]<<[>>+>+<<<-]>>>[<<<+>>>-]<<[>>+<<-]>>[<-<+>>-]<
最後に1カ所「+」が「−」に変わっただけであとは加算と全く同じなので省略にょ。
続いては乗算のコードにょ。(94文字)
,>,>++++++++[<------<------>>-]<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[<<[>>>+<<<-]>>>[<<+<+>>>-]<-]<
2重ループを使っているけど多重ループはデフォ状態のPetit Brainfuckではオプション扱いに
なっているので追加対応しておかないと動作はしないにょ。
加算と同じくポインタ0、1の値を48ほどマイナスしたあとポインタ0の値をポインタ3にコピー
しているにょ。
「ポインタ1の値をポインタ4に移動した後にポインタ4の内容をポインタ1、2に移動」という
ものをポインタ3の値の回数だけ繰り返しているにょ。
乗算は加算を繰り返せばいいだけなんだけどBrainfuckの場合はループのカウンタ用に使って
いるものは破壊されているため2重ループの外側のループでそのカウンタの元になっている
値を初期化させる(3回ループならば値を3に戻す)必要があるにょ。
最後はいよいよ除算にょ。(96文字)
,>,>++++++++[<------<------>>-]<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[<<[>>>+<<<-]>>>[<-<<+>>>-]<<+>]<
乗算が加算の繰り返しならば除算は減算の繰り返しとなるにょ。
実はこれは割り切れるものでないと計算ができない不完全なコードであるためあえて解説は
しないにょ。
減算を繰り返していって本来ならば「除数>余り」になった時点でループから抜けなく
てはならないのだけどそのいい処理が思いつかなかったにょ。
昔、マシン語で除算のプログラムを組んだときはキャリーフラグを元に判断をしていたの
だけどBrainfuckではそういうこともできないからね。
まぁすでに除算のコードを書いている人はたくさん居るのでそれを見れば簡単なのだけど
何とか自力でやってみたいにょ。(リベンジはいつになるのか分からないけど)
というわけでとりあえず除算が不完全であるものの一応四則演算はできたにょ。
Brainfuckで多重ループをさせるコードは初めて書いたけどさすがに難しいにょ。
キー入力した2つの値の加算なんてBASICで書けばめちゃくちゃ簡単にょ。
INPUT A
INPUT B
C=A+B
というだけのことだからね。
これが難解プログラミング言語の難しさであり面白さでもあるにょ。
Brainfuckを完全にマスターすればアクションゲーム(リアルタイムで動作するゲーム)
以外のものは作ることが可能でありオセロゲームくらいならば十分できそうにょ。(しかし
疑似乱数発生のコードまでかかないといけないのでかなりハードルは高そう)
といっても、プチコンの場合は制御文字が使えないため表示場所を指定したコードを書く
ことはできないけどね。(そもそもコードが冗長になってしまうので上限255文字のPetit
Brainfuckでは大した物はできない)
とはいえ、Petit Brainfuckはこの規模のコードを書くならば十分な性能であり、お手軽に
コードを書くには最適といえそうにょ。(PC向けではJavascriptやJavaアプレットで動作
するBrainfuckインタープリタはいくつか試したけどどれも今ひとつで「お手軽」という
感じはしなかった)
《 12/13 追記》
四則演算のコードは初出より少しだけ縮まった(48回デクリメントする処理は短くなると
思っていたコードが実は長かった)ので差し替えておいたにょ。(変えたのはそこだけ)
ちなみに画面出力が何もないというのも何なので「4+2=6」という感じの画面出力に対応
したものもついでに書いておくにょ。(148文字)
>>++++++++[>++++++>++++++>+++++>
++++++++<<<<-]<<,.>>>>>+++.<<<<,
.>>>>>---.<<<[<<-<->>>-]<<<[>>+>
+<<<-]>>>[<<<+>>>-]<<[>>+<<-]>>[
<+<+>>-]<[>>+<<-]>>.
初期に作ってそのまま放置状態なので短縮の余地はかなりありそうにょ。(完全な除算が
できてないので答えが1桁になるもののみ表示可能)
それとは関係ないけど「Petit Brainfuck」は早くも辞書登録を行ったにょ。(通常は
3〜6ヶ月分の新作をまとめてやることが多い)
http://ww5.tiki.ne.jp/~ochame/ochamewords.htm#p_bf
しかし、「ハ行」の語句がやたら多いにょ(プチコン関係のせいだけど)
|
|
|
掲示板管理者へ連絡
無料レンタル掲示板