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

Brainf*ck学第一 第一講義

TM

はじめに

皆さん、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進数の二桁で最大の数はff(16)ff_{(16)}、255を超えると0000になってしまいオーバーフローします。
00から-1した場合もオーバーフローしてff(16)ff_{(16)}になってしまいます。1000なんて論外。めっちゃ不便。

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

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

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

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

イメージ
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

時間が足りない

この記事をシェア

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

関連する記事

2019年4月24日
gnuplotで遊ぼう
mds_boy
2019年4月22日
アセンブリを読んでみよう【新歓ブログリレー2019 45日目】
eiya
2019年4月8日
プログラミングを始めよう【新歓ブログリレー2019 31日目】
idaten
2019年3月25日
春休みのpythonの進捗について【アドベントカレンダー2019 17日目】
owl
2019年3月18日
競プロの最善手
topaz
2019年3月16日
競技プログラミングを始めよう【新歓ブログリレー2019 8日目】
eiya

活動の紹介

カテゴリ

タグ