なすの雑なブログ

雑に書きます

brainf**kのすすめ

この記事は MMA Advent Calendar 2025 の 4日目の記事です。

3日目のさいんさんの記事はこちら

はじめに

こんにちは、電気通信大学MMA 2年のnasuです。前日なのにアドカレの枠が空いていたので急遽書くことにしました。

皆さんはbrainfu*kというプログラミング言語を知っていますか?知っている人は「ネタ言語」や「難解言語」として知っている人が多いと思いますが、書いたことが無い人が多いと思います。それでは勿体ない(?)ので、brainf*ckの文法について紹介します。皆さんもこれを機にbrainf**kを書けるようになりましょう!

そもそもbrainf**kとは?

brainf**kとは、Urban Müllerが「コンパイラがなるべく小さくなる言語」として考案した言語です。そのコンパイラは123バイト*1インタプリタは98バイトと非常に小さいです。可読性・記述性が低いもののチューリング完全なので、さまざまな派生言語を生み出すことになりました。

(出典 Brainfuck - Wikipedia)

実はbrainf**kはちゃんとした思想があって作られたもので、ふざけて作られたネタ言語ではないんです。

文法

brainf**kはメモリを直接操作するようなイメージでプログラムを書きます。具体的には、(最低)30000個の要素を持つ各要素1バイトの配列が0で初期化された状態を初期状態とする配列を操作する感じです。

配列のイメージ
各要素(1byte) アドレス
0 0
0 1
0 2
・・・  
0 29999
0 30000

brainf**kはそのシンプルさから、記述できる命令が8種類しかありません。なので、1分もかからずに全員がbrainf**kを書けるようになります。

まずは全体像を見てみましょう。branf**kの命令は次の4グループに分類できます。定まった名前が見つからなかったので命名は自己流です。

加減算 ポインタ移動 whileループ 入出力
インクリメント:+ 正の移動:> ループ開始:[ 1byte入力:,
 デクリメント:- 負の移動:< ループ終了:] 1byte出力:.

これらを使って最初の表に示したような配列を操作していきます。順番に見て行きましょう。

加減算

ここでいう加減算とは、「現在のポインタが指す値を1増やす/減らす」という意味です。

例えば値が0であるアドレスで加算命令「+」を使うと、そのアドレスの値が0から1に増えます。値が1であるアドレスで減算命令「-」を使うと、1から0になります。また、各要素は1バイトの符号なし整数になっていて、0-1 = 255、255+1=0になります。

ポインタ移動

「正の移動/負の移動」は「ポインタのインクリメント/デクリメント」のことです。

正の移動命令「>」を使うと、「現在のアドレス」から「現在のアドレス+1」に移動します。負の移動命令「<」は「現在のアドレス」から「現在のアドレス-1」に移動します。ただしアドレスはトーラスになっておらず、アドレス「0」に居るときに「<」を使うとエラーになります。

whileループ

ループ命令「[」「]」は高級言語のそれとほとんど同じで、現在のアドレスの値が0ならスキップ/終了を、それ以外ならループ開始/続行を意味します。

入出力

入力命令「,」は、標準入力の先頭1バイトを受け取って現在のアドレスにASCIIの値を格納します。ASCIIに無い字は解釈できず、正しい値として格納されません。

出力命令「.」は、現在のアドレスの値をASCIIとして解釈して標準出力します。

入出力は1バイト(=1文字)ずつ行われるため、複数桁の整数など扱いたい場合は上位桁から1桁ずつ入力/出力する必要があります。

ASCIIコード表はこちら

 

これでbrainf**kの文法は全て分かるようになりました!最後にサンプルプログラムを見てみましょう。

サンプルプログラム

+++++++++++[>++++++>+++++++++>++++++++>++++>+++>+<<<<<<-]>+++
+++.>++.+++++++..+++.>>.>-.<<-.<.+++.------.--------.>>>+.>-.

(brainfuck - Esolangより)

これを実行すると「Hello, World!」と出力されます。やっていることは非常に単純で、メモリの値を出力したい文字に対応する値までインクリメント・デクリメントして出力しているだけです。

 

brainf**kはチューリング完全なので、万能チューリングマシンが計算できる全ての計算ができます。すなわち、高級言語にあるようなif文、for文はもちろん、複雑なアルゴリズムも記述できます。複数桁の数の表現方法に興味がある方はこちら(Esolang)アルゴリズムに興味がある方はこちら(Esolang)を見てみてください。

おわりに

これで皆さんもbrainf**kを書けるようになりましたね。これからは「何となく知っているネタ言語」ではなく「自己表現の道具」としてガンガン使ってみてください。他言語からbrainf**kへのトランスパイラを作ってみても面白いと思います。

最後まで読んでくださりありがとうございました。

明日はsadatchくんの記事です。ぜひそちらも読んでください。

*1:Esolangによると240バイト