Brainfuckに初挑戦して完成させるまでの記録
TSG Advent Calendar 2019 19日目です。
Brainf*ck Advent Calendar 2019 19日目です。
両方とも、前日も私が書いてます。
はじめに
Szkieletorと申します。
書くに至った経緯やお題などは昨日の記事を読んでください。
この記事ではプログラムができるまでの試行錯誤、つまづいたポイントと助けになってページ・ツールなどを書いていきます。
挑戦中
書き始め
「Brainf*ckで九九判定のプログラムを書くぞ!」と意気込んでまずは8つの記号の説明を読みましたが、これでどうプログラムするのかはさっぱりでした。
ただ私の所属するTSGは、コードゴルフ大会を部内で開催するなどesolangについての知見があり、詳しい部員の方(bitmathさん、昨日の記事のリンクの五月祭Day3と駒場祭でコードゴルフ大会の実況解説をしています)が「こんなのがあるよ!」と教えてくれました。それがこちらのBrainfuck Visualizerです。
このヴィジュアライザはデフォルトでHello, Worldのプログラムが置いてあり、その実行過程をセルの状態を眺めながら追えたので、非常に助かりました。Brainf*ck入門者にはとてもおすすめですね。
その後、九九判定ということでこのページでまず掛け算の実装を追い、自分のケースに置き換えて実装しました。このあたりで「あっループ回す値は必然的に0になるから後で使いたい場合はコピーしておかないといけないんだな~」など、初歩の作法を理解し始めました。
中盤
9回のループを2重に回して、その値は掛け算にも使うからコピーして……みたいなことをひとつひとつ実装していました。
あとは九九の積と入力の一致判定で詰まったりしていましたが、Esolang wiki - Brainfuck algorithmsが非常に役に立ちました。これもbitmathさんに教えてもらった。
x=x==y
をちょうど必要としていたので使わせていただいたんですが、このロジックをちゃんと理解することでBrainfuckの作法がだいぶ分かった気がします。
ここらへんからソースコードがちょっとかわいいな……と思い始めました。 -[>+<]-
みたいにループ節はたいてい進んだ分だけ戻るので対称性があってかわいいですよね。伝われ。
終盤
「だいたい実装したけどうまくいかないな……。ヴィジュアライザは速度が遅いし、逆再生できないから使いづらい……」となってつらくなったんですが、TSGとKMC(京大マイコンクラブ)のSlackがつながっていた関係で、primeさん作のデバッガと出会いました。実行時間を調整できることと逆再生の機能がめちゃくちゃありがたかったです。たぶんデバッガがあるという事実を知らなかったら挫折していたと思います。
あとは思っていたのと違う挙動をひとつずつ潰しながらテストして、直して……を繰り返して、繰り返して、ひたすら繰り返して、完成です。
デバッグはつらかったですが、正答を返して改行を取り去ったパッと見全くわからないコードを眺めて、これを書いたんだなあ、何のプログラムか全然わかんないや……と感慨に浸れるのはいいですね。それからprimeさんbitmathさんはじめ周囲(?)の支えがあってこその完成だなと、メダルを取ったアスリートみたいな感想を抱きました。
振り返って
つまずきポイントその他
- やっぱり掛け算とかif文、==などの比較を自力で思いつくのは無理があるので、その実装を理解しながら書いていくとちょうどいいんじゃないかな、と。
- 汎用言語に慣れきっていたので整数と文字列をいったりきたりしないといけない点にはじめにつまずきました。
- 元になったPythonのコードではfor-else文を使ったりして二重ループから脱出していましたが、Brainfuckで「数が一致したらループを抜けて出力処理に入る」方法を思いつけませんでした。結局途中で一致しても81回ループは回る(九九全部計算する)方法に変更。
- セルの値はたいてい最後にはゼロになるので、ときどきゼロにならないセルを見落としてデバッグで苦しんでいました。ループが止まらなくなったらたいていこれか、ポインタの戻し忘れ。
- セルを結局15個くらい使ったのですが、途中で#2と#11の比較をするせいで
>>>>>>>>>(処理)<<<<<<<<<
みたいなことをしています。もっと上級者なら全体を見通して最適なセル配置ができるのかな。 - ビジュアライザとデバッガの存在がめちゃくちゃありがたかったです。めちゃくちゃありがたかったです。
コードゴルフについて
さて、今回挑戦したお題ももともとは学祭のコードゴルフ大会のお題でして、完成したあとじゃあここからどう縮められるだろう? と考えてました。
思いつくところでは、
- セルの再利用――今回はほとんどセルを再利用しなかったんですが、先ほども書いた通りたいていのセルは0になる or 0にするので、再利用できます。するとセル間の距離が近くなり、コードが縮みます。
- ただし、デバッグがつらくなりそう
>>
と<<
は連続していた場合打ち消せる――間違いのないようにいちいち基準になるセルに戻ってから移動……という手順を踏んでいたんですが、これも打ち消せば減らせますね。- これもデバッグがつらくなりそう
書いてて思ったんですが、ゴルフがデバッグをつらくするのは当然ですね。やっぱりアルゴリズム的な改善のほうが大きく縮みそうな気がします。ほんとかな?
あと、もうネットの海に放流されているので手遅れなんですが、五月祭コードゴルフ大会の実況で「(Brainfuckを手で書く人々は)マゾヒストなんですか? w」と発言したことをおわびしておきます。
あとがき
今回紹介したページやツールの助けがあればかなり敷居が下がりますし、界隈の方々はとてもやさしいので、皆さんもぜひBrainfuckプログラミングの世界に足を踏み入れてみてはいかがでしょうか。
アドベントカレンダーの明日の記事は、
ここまで読んでいただきありがとうございました。