FizzBuzzを1byteで実装する
が面白かったので、FizzBuzzを0byteで実装できる言語を作ってみた。(手抜き)
FizzBuzz文字列
まず、正の整数 n について、「nまでのFizzBuzz文字列」を以下のように定義する。
整数 $i = 1, \ldots, n$ について、 $S_i$ を以下のように定義する。
- $i$ が15の倍数のとき $S_i$ は "FizzBuzz"
- $i$ が15の倍数ではなく、かつ3の倍数のとき $S_i$ は "Fizz"
- $i$ が15の倍数ではなく、かつ5の倍数のとき $S_i$ は "Buzz"
- $i$ が3の倍数でも5の倍数でもないとき $S_i$ は $i$ を0~9のアラビア数字を通常の意味で用いて十進数で表した文字列。ただし、一番左の文字は必ず0以外とし、カンマ・小数点・空白など0~9以外の文字は用いない。
整数 $i = 1, \ldots, n$ について、$T_i$ を $S_i$ の後ろに1個の改行を結合した文字列と定義する。
「nまでのFizzBuzz文字列」を、$T_1, T_2, \ldots, T_n$ をこの順番で結合した文字列と定義する。
FizzBuzzF*ck
言語「FizzBuzzF*ck」は、Brainfuck を以下のように拡張した言語である。
- プログラムの実行開始直前 (配列をゼロで初期化した後) に、配列の先頭から連続した部分に、1要素に1文字ずつ「100までのFizzBuzz文字列」を1個格納する。ただし、文字コードはASCIIとし、「改行」は1個のLF (0x0A) とする。配列の余った部分はゼロのままとする。配列の要素数が足りない場合は「100までのFizzBuzz文字列」の配列に収まる最初の部分のみを格納する。
- プログラムの実行終了直後に、1回、配列のポインタが指している要素からポインタ以降初めてゼロが現れる直前の要素までを出力する。すなわち、
[.>]
を実行する。ただし、同じ要素は高々1回のみ出力する。
プログラムの最初に [-]>[>]<[[-]<]
を実行することで、配列をゼロで初期化してポインタを配列の先頭に戻せる。
これはBrainfuckの初期状態と同じである。
さらに、プログラムの最後に [-]
を実行することで、配列のポインタが指している要素をゼロにでき、出力を抑制できる。
これらを用いることで、任意の Brainfuck のプログラムを FizzBuzzF*ck に移植できる。
なお、Brainfuck とは異なり、FizzBuzzF*ck の F*ck は大文字の F とアスタリスクを用いるのが正式な表記である。
処理系
実行例
$ wc examples/fizzbuzz.fbf
0 0 0 examples/fizzbuzz.fbf
$ python fizzbuzzf_ck.py examples/fizzbuzz.fbf
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
31
32
Fizz
34
Buzz
Fizz
37
38
Fizz
Buzz
41
Fizz
43
44
FizzBuzz
46
47
Fizz
49
Buzz
Fizz
52
53
Fizz
Buzz
56
Fizz
58
59
FizzBuzz
61
62
Fizz
64
Buzz
Fizz
67
68
Fizz
Buzz
71
Fizz
73
74
FizzBuzz
76
77
Fizz
79
Buzz
Fizz
82
83
Fizz
Buzz
86
Fizz
88
89
FizzBuzz
91
92
Fizz
94
Buzz
Fizz
97
98
Fizz
Buzz
$
おまけ
冒頭で紹介した記事には、Qiita版が存在する。
FizzBuzzを1byteで実装する - Qiita
おまけ2
実は15年くらい前から似たコンセプトの言語あった…