Best self documenting program
最高の自己説明的なプログラム
受賞者:Qiming HOU
引用元:https://www.ioccc.org/2011/hou/hou.c
審査員・作者による説明:https://www.ioccc.org/2011/hou/hint.html
動作
関数電卓。
$ gcc -o hou hou.c -lm
$ ./hou 11/26+222/31
7168.000000
$ ./hou 'log((21701-19937)-(23209-21701))/log(2)'
-78.036946
$ ./hou 'sin(1.5708)+0.04321+log(sqrt(exp(1*1*1)))+(1+2*3)-0.4-0.6+(4+6)*(2-1+2*3)-tan(0.785398)+2*10/3*6*sqrt(16/2/2)*10+10000-1000'
10155.049091
解説
このコードはかなり驚異的。
コード形状は電卓だが、単なる見せかけではなく、このボタンの中身がきちんと意味のあるコードとして利用されている。
すばらしい。
例として書かれているusage: calculator 11/26+222/31
や、その計算結果の7.584,367
もコードとして意味のある数字になっている。
これらの数字を使いつつ、式の識別子を判別する値を計算で作り出す。
おそらくブルートフォースかなにかで都合の良い数字を探しだしたのだと思う。
そして、判別用の数字をデクリメントしつつ分岐し、電卓のアスキーアート中にあるtan
やsqrt
を実際に関数名として使うことで関数を呼び出す(tan
とcos
とsin
がバラバラの位置にあるのは判別用の数字の都合)。
また、(/)
や(+)
などもそれぞれの演算子を入力文字列からパースするために用いられている。
優先順位付きのパースは、main
関数の第1引数をうまく使って行っている(と思う、詳細まで解読していない)。
制限としては、argv[1]++
をするのでargv
が書き換え可能でないといけない(文字列自体は書き換えない)。
また、1e-4
みたいな記法は動かない。