引用元:https://www.ioccc.org/2020/carlini/prog.c
審査員・作者による説明:https://www.ioccc.org/2020/carlini/index.html
動作
○×ゲーム。
$ gcc -o prog prog.c
$ ./prog
...(大量の空白やゴミ文字)...
| |
-----
| |
-----
| |
P1>
左上から各マスに1~9まで番号が振られている。
3を指定する例。
P1>3
...(大量の空白やゴミ文字)...
| |X
-----
| |
-----
| |
P2>
AIは搭載されていないので、同様に手入力していく。
不可能な手を打つか、勝敗が決定するか、全マスが埋まったら終了する。
O| |X
-----
|O|X
-----
| |X
P1 WINS
解説
main
関数がprintf()
の繰り返しだけになっている。
マクロでごまかしているなどではなく、実際にこのようになっている。
int main() {
while(*d) printf(fmt, arg);
}
ポイントは、%n
というマイナーなprintf()
フォーマット指定子。
コード形状もそれを表現している。
これはポインタを引数に受け取り、printf()
がここまでに書いた文字数をそのポインタに書き込む。
%hhn
とすればchar
型へのポインタとして扱ってくれるので、実質256の剰余も計算できる。
さらに%2$hn
のような引数位置の指定もあわせることで、できることが増える。
hint.textには2進演算の考え方がわかりやすく書いてある。
もちろん、効率的に実行するにはそれ以上の工夫が必要となるとのこと。
なお、入力はscanf()
で行っている。
最初は空文字列でscanf()
することで何も読み込まず、2度目からはprintf()
によってscanf()
のフォーマット文を有効にすることで、位置の入力を受け取るようになる。