Factoradic Decoder

#久しぶりのブログ更新。ずいぶん間が空いてしまった。
一連の、Factoradic 問題が先ほど終了した。その中で、Factoradic Decoder では、C言語で、79B@hinoe さんに 3B 差で負けた。hinoe さんの解を見ると、全体的な方針は同じだが for 文の一重化で差がついている。この方針でも一重化ができるとは。さすがですね。以下比較のために引用。

r;main(i,p)char*p;{for(;r||gets(p);r*=strlen(++p)?:!printf("%d\n",r))r+=*p-48;}
main(v,p)char*p;{for(;gets(p);printf("%d\n",v))for(v=0;*p;)v=*p++%48+v*strlen(p);}

しかしこの2つを比べると、for 文の一重化の定式化は、相当に難しいな。というか無理なんではないだろうか。このケースの場合、

v=*p%48+v*strlen(p)

という式を

r+=*p-48
r*=strlen(p)?:...

という2式に分解することで、printf() 出力のタイミングと、ループ条件、r||gets(p) において、まず、gets(p) に制御を移すことを実現している(もちろん、hinoe さんがたどった道筋がこの通りとは限らないが。。。)。つまり、2重 for 文における各式の内容をどう分解・変形できるかまで突っ込んで考えないと for 文1重化の定式化は無理だということ。しかしながら、経験的に C 言語において、for 文1重化により短くなる割合はかなり高いな。