Brainf*ckでHello world!出力してみた。

# 自己紹介

こんにちは。STECHのdaveです。普段は楽天やZOZOでSREのインターンをしたり、クラウドネイティブ関連のテクノロジーについてキャッチアップしたり、Vue.jsとEchoでwebサービスを個人で開発したりしております。

# この記事を書こうと思ったきっかけ

STECHでは真面目な技術の話しかしていないので何か技術でふざけたい、それでもコンピュータサイエンスとして知見のある話をしたいと思った結果、変わったプログラミング言語について話すことにしました。今回は、有名ですが書き方がそこまで知られていないBrainf*ckをご紹介したいと思います。

# Brainf*ckとは　

Brainf\*ckは難解プログラミング言語 (esoteric programming language, esolang)の1種です。可読性のへったくれもありませんが、チューリング完全なので学術的に面白い言語だと個人的に思ってます。
Brainf*ckは1バイトのセルが30,000個あり、ポインタを移動させたり、セルの値を変えたりして出力を変えていきます。　

Brainfuckの命令はなんと8種類しかありません。

|  命令  |  意味  |
| ---- | ---- |
|  <  |  ポインタを1つ左にずらす  |
|  >  |  ポインタを1つ右にずらす  |
|  +  |  セルの値を1増やす  |
|  -  |  セルの値を1減らす  |
|  .  |  セルの値を表示する  |
|  ,  |  標準入力の文字をセルに保存する  |
|  [  |  ポインタが0になったら次の]に戻る　 |
|  ]  |  ポインタが0でなければ以前の]に戻る  |　


# Brainf*ckでHello world!を書いてみた
プログラム言語の定番ですが、Hello world!を出力してみます。
文章を出力するために、各文字の文字コードを出力する必要があります。
Hello world!の文字コードは以下の通りです。
|  文字  |  文字コード  |  前の文字コードとの差分  |
| ---- | ---- | ---- |
|  H  |  72   |  72  |
|  e  |  101  |  29  |
|  l  |  108  |  7   |
|  l  |  108  |  0   |
|  o  |  111  |  3   |
|     |  32   | -79  |
|  w  |  119  |  87  |
|  o  |  111  |  -8  |
|  r  |  114  |  33  |
|  l  |  108  |  -6  |
|  d  |  100  |  -8  |
|  !  |  33   |  -67 |

1番右の差分を素直に実装すると、以下の通りになります。

```brainfuck
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.
+++++++++++++++++++++++++++++.
+++++++.
.
+++.
-------------------------------------------------------------------------------.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.
--------.
+++.
------.
--------.
-------------------------------------------------------------------.

```
もしご興味のある方は[brainf\*ckのオンラインエディタ](https://ideone.com)で動作確認して下さい。
各行は差分を+/-で表現した後に、`.`で出力しています。しかしこれらを愚直に書くのは面倒なので、もっと楽したいですよね。実は以下のように短縮できます。
```brainfuck
++++++++[->+++++++++<]>.
<+++++[->+++++<]>++++.
+++++++.
.
+++.
<+++++++++[->---------<]>++.
<+++++++++[->+++++++++<]>++++++.
--------.
+++.
------.
--------.
<++++++++[->--------<]>---.
```

1行目の`72 = 8 x 9` をbrainf\*ckで表現してみます。まずは2つのセルを準備しましょう。　
左のセルにインデックス、右のセルに実際の値を格納します。　左のセルには`++++++++`で8を予め入れておきます。

|  8  |  0  | 
| -- | -- |

まずは左のセルの値を`-`で1減らします。　
次にポインタを`>`で右に1つずらし、右のセルに`+++++++++`に9を足します。　
更に`<`でポインタを左にずらし、下の状態になります。

|  7  |  9  | 
| -- | -- |

これが `->+++++++++<`の1ループ分です。
同じようなことを`[->+++++++++<]`で複数回繰り返します。

2回目
|  6  |  18  | 
| -- | -- |

3回目
|  5  |  27  | 
| -- | -- |

4回目
|  4  |  36  | 
| -- | -- |

5回目
|  3  |  45  | 
| -- | -- |

6回目
|  2  |  54  | 
| -- | -- |


7回目
|  1  |  63  | 
| -- | -- |

8回目
|  0  |  72  | 
| -- | -- |

左のセルの値が0になったので、ループ終了です。　
最後に`>`でポインタを右にずらし`.`で値を表示します。　
これが`++++++++[->+++++++++<]>.`の内容です。　

同じことを全ての行で実行していきます。末尾の+/-の調整は、brainf\*ckでも+/-でベタ書きします。
```
72 = 8 x 9
29 = 5 x 5 + 4
7 = 1 x 7
3 = 1 x 3
-79 = -9 x 9 + 2
87 = 9 x 9 + 6
-8 = -1 x 8
33 = 6 x 6 - 3
-6 = -1 x 6
-8 = -1 x 8
-67 = -8 x 8 - 3
```
各行をbrainf\*ckで表現した式が以下の通りです。
```brainfuck
++++++++[->+++++++++<]>.
<+++++[->+++++<]>++++.
+++++++.
.
+++.
<+++++++++[->---------<]>++.
<+++++++++[->+++++++++<]>++++++.
--------.
+++.
------.
--------.
<++++++++[->--------<]>---.
```
これを1行にまとめると、ここまで短縮できます。
```brainfuck 
++++++++[->+++++++++<]>.<+++++[->+++++<]>++++.+++++++..+++.<+++++++++[->---------<]>++.<+++++++++[->+++++++++<]>++++++.--------.+++.------.--------.<++++++++[->--------<]>---.
```

これでBrainf\*ckで`Hello world!`を出力できました！　

# 終わりに　
Brainf*ckは全くを以て実用に耐える言語ではありませんが、純粋に興味深いプログラミング言語だと思いました。皆さんも難解プログラミング言語で遊んでみてはいかがでしょうか？