引用元:https://www.ioccc.org/2018/vokes/prog.c
審査員・作者による説明:https://www.ioccc.org/2018/vokes/hint.html
動作
グラフの強連結成分を取り出す。
次が入力データの例。
$ cat tmp.txt
0 1
1 2
2 3
3 0
4 1 2 6
5 4
6 5
7 5
これは、0から1への辺があり、1から2への辺があり、……ということを表現している、図にすると次の通り。
0 ---> 1 <--- 4 <--- 5 <--- 7
^ | / \ ^
| V / \ |
3 ---- 2 <-+ +-> 6
実行すると、0、1、2、3は強連結成分(どの2要素にも互いに接続パスがある)、4、5、6も強連結成分、7は単体で強連結成分と判定される。
$ gcc -o prog prog.c
$ ./prog < tmp.txt
0: 0 1 2 3
1: 4 5 6
2: 7
解説
Tarjanの強連結成分分解のアルゴリズムを実装している。
トポロジカルソートをベースにしたもの。
コードは、全体的に魔術をテーマに彩っている。
コード形状は泡立つ大釜(bubbling cauldron)。
関数名はなんとなく魔女が何か作っていそうな単語。
meltdown(融解)、magic(魔法)、cast(Cのキャストではなく鋳造)、spell(呪文)、witch(魔女)、newt(イモリ)、bubble(泡)、boil(茹でる)、hex(16進ではなくまじない)、toil(網)、nasal_demons(鼻から悪魔)、brew(醸造)、potion(薬)、bat(コウモリ)、toad(カエル)、spectre(妖怪) 、familiar(使い魔)。
引数の数の違う関数を同じ関数ポインタに入れている(呼び出し時に一致していれば大丈夫)。
i
はループ変数ではなく、argv
とargc
は入れ替わっている。
argc[argv]
をNULL
の代わりに使う。