猿でもわかる
難解プログラミング言語
3年5組 ****
TwitterID @3_3_nk
自己紹介とか
■ みみねこです
– フォローしてください
■ アイコン描いてもらった!!
– ゆき(@TNCT_yuki)さんからです
– ファンアートお待ちしてます
■ プロコン競技部門予選突破!!
– がんばります
突然ですが
キーボードのキーが
突然反応しなくなるときって
ありますよね
キーボードの「A」キー以外
全部反応しなくなるときって
ありますよね
キーボードが「A」キー以外
全部反応しなくなったけど
プログラミングしなきゃいけないとき
ありますよね
そんな時に知っておくと便利なのが
プログラミング言語「A」!!!
プログラミング言語「A」とは?
■ 「A」という文字だけで記述するのが最大の特徴
– 他の文字や改行や空白などはすべてコメント扱いとなる
– むしろこれしか特徴がない
■ 「A言語」とは明確に異なるため、言語「A」と表記
■ 難解プログラミング言語のひとつである
■ Brainfuckから派生した言語のひとつである
プログラミング言語「A」とは?
■ 「A」という文字だけで記述するのが最大の特徴
– 他の文字や改行や空白などはすべてコメント扱いとなる
– むしろこれしか特徴がない
■ 「A言語」とは明確に異なるため、言語「A」と表記
■ 難解プログラミング言語のひとつである
■ Brainfuckから派生した言語のひとつである
Brainfuckとは?
■ 難解プログラミング言語のひとつ
■ 8種類の文字のみをつかって記述するのが最大の特徴
■ コンパイラのサイズをなるべく小さくしようとしてできた
言語(らしい)
ということは
■ Brainfuckを理解すれば言語「A」も理解できる
■ →Brainfuckを学んでおけばキーボードがいつ壊れてもプ
ログラミングできる!!!!
■ →Brainfuckを学ぼう!
Brainfuckの言語仕様
■ 言語仕様について
– 無限長のメモリ(配列のようなもの)が一つと、そのメモリのあ
る要素を指すポインタがある
– メモリのすべての要素は実行時に0に初期化され、ポインタは
最初0番目の要素を指している
– 変数などないので、すべての値はこのメモリ上で管理する
Brainfuck講座
■ 使う文字は8種類のみ
■ 各文字には独立した命令が割り振られている
■ 関係ない文字はすべてコメント扱いされる
文字の種類 命令 C言語で対応する構文
> ポインタを1増やす ptr++;
< ポインタを1減らす ptr--;
+ 要素の値を1増やす (*ptr)++;
- 要素の値を1減らす (*ptr)--;
. 要素を出力する putchar(*ptr);
,
入力を1バイト受け取り
要素に代入する *ptr = getchar();
[ 要素が0なら]まで飛ぶ while(*ptr){
] [まで飛ぶ }
文字の種類 命令 C言語で対応する構文
> ポインタを1増やす ptr++;
< ポインタを1減らす ptr--;
+ 要素の値を1増やす (*ptr)++;
- 要素の値を1減らす (*ptr)--;
. 要素を出力する putchar(*ptr);
,
入力を1バイト受け取り
要素に代入する *ptr = getchar();
[ 要素が0なら]まで飛ぶ while(*ptr){
] [まで飛ぶ }
>> <<
{0} {1} {2} {3} {4} {5}
0 0 0 0 0 0
☝
>> <<
{0} {1} {2} {3} {4} {5}
0 0 0 0 0 0
☝
>> <<
{0} {1} {2} {3} {4} {5}
0 0 0 0 0 0
☝
>> <<
{0} {1} {2} {3} {4} {5}
0 0 0 0 0 0
☝
>> <<
{0} {1} {2} {3} {4} {5}
0 0 0 0 0 0
☝
文字の種類 命令 C言語で対応する構文
> ポインタを1増やす ptr++;
< ポインタを1減らす ptr--;
+ 要素の値を1増やす (*ptr)++;
- 要素の値を1減らす (*ptr)--;
. 要素を出力する putchar(*ptr);
,
入力を1バイト受け取り
要素に代入する *ptr = getchar();
[ 要素が0なら]まで飛ぶ while(*ptr){
] [まで飛ぶ }
++ > --
{0} {1} {2} {3} {4} {5}
0 0 0 0 0 0
☝
++ > --
{0} {1} {2} {3} {4} {5}
1 0 0 0 0 0
☝
++ > --
{0} {1} {2} {3} {4} {5}
2 0 0 0 0 0
☝
++ > --
{0} {1} {2} {3} {4} {5}
2 0 0 0 0 0
☝
++ > --
{0} {1} {2} {3} {4} {5}
2 -1 0 0 0 0
☝
++ > --
{0} {1} {2} {3} {4} {5}
2 -2 0 0 0 0
☝
文字の種類 命令 C言語で対応する構文
> ポインタを1増やす ptr++;
< ポインタを1減らす ptr--;
+ 要素の値を1増やす (*ptr)++;
- 要素の値を1減らす (*ptr)--;
. 要素を出力する putchar(*ptr);
,
入力を1バイト受け取り
要素に代入する *ptr = getchar();
[ 要素が0なら]まで飛ぶ while(*ptr){
] [まで飛ぶ }
, ++ .
{0} {1} {2} {3} {4} {5}
0 0 0 0 0 0
☝
A
, ++ .
{0} {1} {2} {3} {4} {5}
65 0 0 0 0 0
☝
A
, ++ .
{0} {1} {2} {3} {4} {5}
66 0 0 0 0 0
☝
A
, ++ .
{0} {1} {2} {3} {4} {5}
67 0 0 0 0 0
☝
A
, ++ .
{0} {1} {2} {3} {4} {5}
67 0 0 0 0 0
☝
A C
文字の種類 命令 C言語で対応する構文
> ポインタを1増やす ptr++;
< ポインタを1減らす ptr--;
+ 要素の値を1増やす (*ptr)++;
- 要素の値を1減らす (*ptr)--;
. 要素を出力する putchar(*ptr);
,
入力を1バイト受け取り
要素に代入する *ptr = getchar();
[ 要素が0なら]まで飛ぶ while(*ptr){
] [まで飛ぶ }
[->+<]
{0} {1} {2} {3} {4} {5}
3 0 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
3 0 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
2 0 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
2 0 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
2 1 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
2 1 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
2 1 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
2 1 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
1 1 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
1 1 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
1 2 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
1 2 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
1 2 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
1 2 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
0 2 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
0 2 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
0 3 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
0 3 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
0 3 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
0 3 0 0 0 0
☝
[->+<]
{0} {1} {2} {3} {4} {5}
0 3 0 0 0 0
☝
プログラム例1:echo
■ いわゆるオウム返しプログラム
■ 入力をそのまま出力する
■ Brainfuckで実装するとなんと5byteで書ける
,[.,]
{0} {1} {2} {3} {4} {5}
0 0 0 0 0 0
☝
TNCT
,[.,]
{0} {1} {2} {3} {4} {5}
84 0 0 0 0 0
☝
TNCT
,[.,]
{0} {1} {2} {3} {4} {5}
84 0 0 0 0 0
☝
TNCT
,[.,]
{0} {1} {2} {3} {4} {5}
84 0 0 0 0 0
☝
TNCT T
,[.,]
{0} {1} {2} {3} {4} {5}
78 0 0 0 0 0
☝
TNCT T
,[.,]
{0} {1} {2} {3} {4} {5}
78 0 0 0 0 0
☝
TNCT T
,[.,]
{0} {1} {2} {3} {4} {5}
78 0 0 0 0 0
☝
TNCT T
,[.,]
{0} {1} {2} {3} {4} {5}
78 0 0 0 0 0
☝
TNCT TN
,[.,]
{0} {1} {2} {3} {4} {5}
67 0 0 0 0 0
☝
TNCT TN
,[.,]
{0} {1} {2} {3} {4} {5}
67 0 0 0 0 0
☝
TNCT TN
,[.,]
{0} {1} {2} {3} {4} {5}
67 0 0 0 0 0
☝
TNCT TN
,[.,]
{0} {1} {2} {3} {4} {5}
67 0 0 0 0 0
☝
TNCT TNC
,[.,]
{0} {1} {2} {3} {4} {5}
84 0 0 0 0 0
☝
TNCT TNC
,[.,]
{0} {1} {2} {3} {4} {5}
84 0 0 0 0 0
☝
TNCT TNC
,[.,]
{0} {1} {2} {3} {4} {5}
84 0 0 0 0 0
☝
TNCT TNC
,[.,]
{0} {1} {2} {3} {4} {5}
84 0 0 0 0 0
☝
TNCT TNCT
,[.,]
{0} {1} {2} {3} {4} {5}
0 0 0 0 0 0
☝
TNCT TNCT
,[.,]
{0} {1} {2} {3} {4} {5}
0 0 0 0 0 0
☝
TNCT TNCT
,[.,]
{0} {1} {2} {3} {4} {5}
0 0 0 0 0 0
☝
TNCT TNCT
,[.,]
{0} {1} {2} {3} {4} {5}
0 0 0 0 0 0
☝
TNCT TNCT
プログラム例2:Hello World!!
■ 新しくプログラミング言語に触ったらまずはこれ
■ Brainfuckだと少し面倒くさいけど、書けます
++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++.
++++++++++ ++++++++++ +++++++++.
+++++++. . +++.
---------- ---------- ---------- ----------
---------- ---------- ---------- ---------.
++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ +++++.
++++++++++ ++++++++++ ++++. +++.
------. --------.
---------- ---------- ---------- ----------
---------- ---------- -------. . (366byte)
プログラム例2:Hello World!!
■ 愚直に書くと366byte
■ 少し改良すると短いプログラムになる
++++++++
[->+++++++++>+<<]>
[->>+>+>+>+<<<<<]>
++++
[->+++>++>+>>+++<<<<<]>>>>
.<<+++++.<..+++.>>>>----.
<<+++.<<.+++.------.>-.>>>+..
(127byte)
Brainfuckの派生言語について
■ Brainfuckでは、文字ごとに命令が独立している
■ つまり、文字を単語に置換するだけでも派生言語ができ
る!!
派生言語の例1:Nyaruko
■ https://github.com/masarakki/nyaruko_lang
■ アニメ「這いよれ!ニャル子さん」のOPの歌詞弾幕で
Brainfuckの文字を置換した言語
■ 先ほどのHello World!!(127byte)を変換してみます
(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/
にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・
ω・)/にゃー!CHAOS☆CHAOS!(」・ω・)」うー!!!(/・ω・)/にゃー!!!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/
にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・
ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」
うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・
ω・)」うー!!(/・ω・)/にゃー!!I WANNA CHAOS!(」・ω・)」うー(/・ω・)/にゃーCHAOS☆CHAOS!(」・ω・)」うー!!!(/・ω・)/
にゃー!!!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・
ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー
(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・
ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!I WANNA CHAOS!(」・ω・)」
うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・
ω・)」うー!(/・ω・)/にゃー!CHAOS☆CHAOS!(」・ω・)」うー!!!(/・ω・)/にゃー!!!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」
うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・
ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/
にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・
ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」
うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!I WANNA CHAOS!(」・ω・)」うー
(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃーLet's\(・ω・)
/にゃー(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」
うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!Let's
\(・ω・)/にゃー(」・ω・)」うー!!(/・ω・)/にゃー!!Let's\(・ω・)/にゃーLet's\(・ω・)/にゃー(」・ω・)」うー!(/・ω・)/
にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!Let's\(・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー
(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!!!(/・ω・)/
にゃー!!!(」・ω・)」うー!!!(/・ω・)/にゃー!!!(」・ω・)」うー!!!(/・ω・)/にゃー!!!(」・ω・)」うー!!!(/・ω・)/にゃー!!!Let's\(・ω・)
/にゃー(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」
うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!Let's\(・ω・)/にゃー(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」
うー!!(/・ω・)/にゃー!!Let's\(・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」
うー!(/・ω・)/にゃー!Let's\(・ω・)/にゃー(」・ω・)」うー!!!(/・ω・)/にゃー!!!(」・ω・)」うー!!!(/・ω・)/にゃー!!!(」・ω・)」
うー!!!(/・ω・)/にゃー!!!(」・ω・)」うー!!!(/・ω・)/にゃー!!!(」・ω・)」うー!!!(/・ω・)/にゃー!!!(」・ω・)」うー!!!(/・ω・)/
にゃー!!!Let's\(・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!!!(/・ω・)/にゃー!!!Let's\(・ω・)/にゃー(」・
ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/
派生言語の例2:Ook!
■ http://www.dangermouse.net/esoteric/ook.html
■ オランウータン向けのプログラミング言語
■ 「Ook.」「Ook!」「Ook?」の3つの鳴き声だけで記述す
る
– それ以外の文字を含めるとエラー(オランウータンは喋れない
ので)
■ 人間向けではないので、変換したコードは貼りません
派生言語の例3:言語「A」
■ やっと本題です
■ 先ほどのOok!は3つの種類の単語のみで記述していたが、
言語「A」は「A」のみで記述する
■ Aの個数で8つの命令を判別する
「A」の個数 命令
Brainfuckで対応する
文字の種類
0個 ポインタを1増やす >
1個 ポインタを1減らす <
2個 要素の値を1増やす +
3個 要素の値を1減らす -
4個 要素を出力する .
5個 入力を1バイト受け取り
要素に代入する ,
6個 要素が0なら]まで飛ぶ [
7個 [まで飛ぶ ]
「A」が8つ以上ある場合
■ 8で割った商が8未満になるまで、この規則を再帰的に適
用する
■ 8で割った余りで命令を判別する
■ これだとちょっとわかりづらい
言語「A」の簡易表現
■ 実際にAを何個も入力するのは大変
■ そこで、簡易表現として「『A』が8進数でN個続く」と
いうような言い方をする
■ 例えば、5byteのechoプログラムを言語「A」で書くと、
「A」が8進数で56457個続く
– 10進数で23855個
簡易表現するメリット
■ 「A」の個数を上位桁の数字から順に見ていくことで、
人間でも簡単に言語「A」を読める!!
■ Brainfuckのプログラムを数字に置き換えてそれを8進数
として読めば、言語「A」の簡易表現になる
■ あとはその数字の回数分「A」キーを打つだけ!
簡易表現するメリット
■ 「A」の個数を上位桁の数字から順に見ていくことで、
人間でも簡単に言語「A」を読める!!
■ Brainfuckのプログラムを数字に置き換えてそれを8進数
として読めば、言語「A」の簡易表現になる
■ あとはその数字の回数分「A」キーを打つだけ!
■ →猿でもできる!!
簡易表現するメリット
■ 「A」の個数を上位桁の数字から順に見ていくことで、
人間でも簡単に言語「A」を読める!!
■ Brainfuckのプログラムを数字に置き換えてそれを8進数
として読めば、言語「A」の簡易表現になる
■ あとはその数字の回数分「A」キーを打つだけ!
■ →猿でもできる!!
■ →ヒトでもできる!!!!
まとめ
■ Brainfuckが書ければ言語「A」も書ける!
■ いつキーボードが壊れても安心ですね!!
猿でもわかる
難解プログラミング言語
終

プログラミング言語「A」 2019 07 08