feature image

2019年4月19日 | ブログ記事

Brainf*ck学第一 第一講義

はじめに

皆さん、Brainfuckというプログラミング言語は知っていますか?和訳すると大変なことになってしまいますが、言語名の由来は、可読性が低すぎる(コードが見づらい)ために、頭がイかれるというのが意味でBrainfuckという名前が付いています。(出典)
そもそも可読性が低いとはどういうことか、簡単に説明したいと思います。

"Hello, World"を出力してください。
Python:

print("Hello, World")

C++:

#include<iostream>
using namespace std;
int main(){ //ここまでおまじない
    cout << "Hello, World" << endl;
}

プログラミング言語をほとんど知らない人でも、ぱっと見てなんとなくは何が起きるかわかると思います。
では、ここでBFのコード例を見てみましょう。
Brainfuck:

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

これの意味が一瞬でわかった人は言語界の天才かキチガイです。
この言語のことが少しでも理解できるように解説していきます。

この言語の凄い所

まず、この言語には8文字しか使われません。上の"Hello, World"のコードを見てください。

[]<>+-.,

","は今回使っていませんが、たったこれだけの文字でコードが書けてしまうんです。凄くないですか??
さらに、BFはチューリング完全な言語です。つまり、プログラムで処理できる仕事はどんなことでもこの言語で書くことができます。C++やPythonなんていらなかったんや

この言語のヤバい所

はい、この言語はハッキリ言って、マゾが勉強する言語です。意味不明なレベルで難しいです。

イメージ
41   42   00 00 00 00 .....
"A"  "B"  初期状態...

上記イメージの通り、メモリは二桁の16進数で記録されます。16進数の二桁で最大の数は、255を超えるとになってしまいオーバーフローします。
00から-1した場合もオーバーフローしてになってしまいます。1000なんて論外。めっちゃ不便。

イメージ
08 00 00 00 00 00 .....

これを"8"と出力するのは、簡単です。8のASCIIコードであるになるように数字を足してあげれば、この計算結果がめでたくASCIIコードの数字に変換されて保存できました。

イメージ
08 00 00 00 00 00 .....
↓(ASCIIに戻す)
38 00 00 00 00 00 .....
"8"

さて、次の問題です。
5+7=12
今、メモリにはという値が保存されました。

イメージ
0c 00 00 00 00 00 .....

ここからどうやって"12"と出力しましょうか?ASCIIコードには1や2はありますが、12は存在しません。つまり、12と出力するためには01 02のように保存されていないといけません。

出力するときに最適なイメージ
01   02   00 00 00 00 .....
↓(ASCIIに戻す)
31   32   00 00 00 00 .....
"1"  "2"

しかし、上記結果のように、二桁に分ける必要がある場合と無い場合の二通りがあると、この言語は混迷を極めます。
「A%10で10で割った余りを出力して、A/10で10の位を出力すればいいじゃない」と他言語をやったことがある人なら思うかもしれません。
そう、他の言語にとってこの程度全く苦にすらなりませんが(そもそも足し算結果そのまま出力できる)、この言語はわけが違います。たった8文字しかないうえに簡単にオーバーフローする言語が割り算できると思いますか?普通に無理です。
今の結果が二桁なのか、一桁なのかを簡単に判別する方法がありません。ありえん不便。

イメージ
入力:194
31  39  34  ?? 00 00 .....
"1" "9" "4" ↑バグる(Nullなので普通は0)
イメージ
31 00 00 00 .....
↓
31 31 00 00 ....
にしたい
(BF)
[処理A(隣に数字をコピーする)]
イメージ
31 00 00 00 .....
↑ここの数字が0でない限り処理Aを実行します
.......
while文が終わった時
00 31 00 00 ....
↑元あった場所からはデータが消えてしまう

もちろん対策はあるのですが、少なくとも気軽に"tmp=a"のようにコピーが出来ないと言うのは大きな問題ですね。

この言語のメリット

ありません。強いて言うならチューリングテープというプログラミングの原点の考えに非常に似ているので、その勉強になることと、いかにC++やPythonが書きやすく偉大かを嫌というほど理解させてくれます。†C++やPythonは偉大†
いや、ほんと割り算のライブラリとか、256までの出力ライブラリ自作なの意味不明ですから・・・

最後に

マジでただの愚痴ですね、これ。本当はもう少し進めて「本当はできる複数桁の出力!」なんて記事出そうと思ったのですがあまりにも長くなりそうなので次回にします。
この言語はとても面白いので、ぜひ挑戦してみてね。
+++++++++[>++++++++<-]>++++.<+++++++++[>++<-]>+++++++.<+++++++++[>+<-]>++++++.<+++++++++[>--------<-]>-----.<+++++++++[>++++++++<-]>++++.<+++++++++[>---------<-]>--.<+++++++++[>+++++++<-]>++++.+++++.-------.<+++++++++[>+<-]>++..-------.<+++++++++[>+<-]>.-------.--.<+++++++++[>-------<-]>-----.

参考サイト

TM icon
この記事を書いた人
TM

時間が足りない

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

ERC20トークンを用いた宝探しゲーム(真)の提案【アドベントカレンダー2018 10日目】 feature image
2018年11月3日
ERC20トークンを用いた宝探しゲーム(真)の提案【アドベントカレンダー2018 10日目】
Azon icon Azon
2021年5月19日
CPCTF2021を実現させたスコアサーバー
xxpoxx icon xxpoxx
2023年4月27日
Vulkanのデバイスドライバを自作してみた
kegra icon kegra
2024年4月14日
Spotifyのクライアントを自作しよう
d_etteiu8383 icon d_etteiu8383
2021年12月8日
C++ with JUCEでステレオパンを作ってみた【AdC2021 26日目】
liquid1224 icon liquid1224
2019年4月22日
アセンブリを読んでみよう【新歓ブログリレー2019 45日目】
eiya icon eiya
記事一覧 タグ一覧 Google アナリティクスについて 特定商取引法に基づく表記