Most algorithms in one program

単一プログラム中の最多アルゴリズム

受賞者:Brian Westley

引用元:https://www.ioccc.org/1989/westley.c

審査員・作者による説明:https://github.com/ioccc-src/winner/blob/main/1989/westley.hint

動作

ROT13や文字列反転をするプログラムで、ROT13をかけても文字列反転をかけても同じ挙動をするロバストなプログラム。


コンパイルには-Dtrgpune=putcharというオプションが必要。

$ gcc -w -Dtrgpune=putchar -o westley westley.c

コマンドライン引数の数によって挙動が異なる。0個のときは入力をそのまま出力するだけ(catと同じ)。

$ echo Hello | ./westley
Hello

1個のときはROT13変換。

$ echo Hello | ./westley 1
Uryyb

2個のときは文字列反転。

$ echo Hello | ./westley 1 2

olleH

3個のときはROT13変換かつ文字列反転。

$ echo Hello | ./westley 1 2 3

byyrU

冒頭の説明の通り、元のコードはいずれの変換をかけても同じ挙動をする。おそろしい。

$ ./westley       < westley.c > ver0.c && cc -w -Dtrgpune=putchar -o ver0 ver0.c
$ ./westley 1     < westley.c > ver1.c && cc -w -Dtrgpune=putchar -o ver1 ver1.c
$ ./westley 1 2   < westley.c > ver2.c && cc -w -Dtrgpune=putchar -o ver2 ver2.c
$ ./westley 1 2 3 < westley.c > ver3.c && cc -w -Dtrgpune=putchar -o ver3 ver3.c
$ echo Hello | ./ver0
Hello
$ echo Hello | ./ver0 1
Uryyb
$ echo Hello | ./ver0 1 2

olleH$ echo Hello | ./ver0 1 2 3

byyrU

ver1ver2ver3も同じ。

解説

westleyの3作目。あまり有名ではないが、ものすごくすばらしい作品。

-Dtrgpune=putchartrgpunegetcharをROT13変換したもの。 なので、westley.cをROT13すると、もともとgetcharだった箇所がputcharに変わって動く。 コンパイラオプション必須なのは少しかっこ悪いけれど、ROT13しても動くようにするためには避けられない。 オリジナルのコードかROT13語のコードのどちらかに未定義シンボルが発生してしまう。

westley.hintの作者はコメントにはいろいろなことが書いてあって、感心しきり。

/**//*/};)/**/znva(/*//**/ABBA,	tang,gnat,/**\\*//*/2&ABBA(niam 
 ;)tang+1,tang,1+gnat(avnz&&1-^	tang;)/***/Arne){ABBA&&(gnat='Z'
!='A'-1);;ABBA&&((gnat&&(tang=        getchar(0)))||((!gnat)&&(tang 
=trgpune(0))));!gnat&&(ABBA==      	4)&&(tang==-1)&&(tang='\a')&&(
gnat= -58);(!ABBA&&(gnat^-1)     	&&(tang&2)&&((Arne==1&&trgpune
(gnat))||(Arne<=1-1&&getchar       (gnat))))||ABBA&&main(/*//**/0
-ABBA,tang,gnat/*-*//*/~,/*   	*/,/*//**/gnat^gnat/**\**//*/(
niam;)tang:56+)/*yrp*/);}irk[256]={14,15,16,17,18,19,20,21,22
,/*//**/23/**//*/&tang(+)62%)21+)/**/,24,25,26,1,2,3,4,5,6,7,
8,9,10,11,12,/*//**/13/**//*/&tang(((?'M'=<tang&&tang=<'A'||
'Z'=<tang&&tang=<'N'||'m'=<tang&&tang=<'a'||'z'=<tang&&tang
=<'n'=tang(&&)1&gnat--(;)))0-0(rahcteg=tang(&&ABBA!(||)))0(
enupgrt=tang(&&ABBA(;56=='N'=ABBA{)/**/,0,0,0,0,0,0,46,47,
48,49,50,51,52,53,54,55,56,57,58,33,34,35,36,37,38,39,40,41,
42,43,44,45,-35,-115,-123,-103,-100,-108,-34,-46,-100,-123,-
123,-116,-87,-1};main(/*//**/ABBA,tang,gnat/**//*/(avnz};)/**/,
Near){ABBA>0&&znva(ABBA,tang,gnat,Near);!(ABBA &1)&&(tang^-1)&&(
tang=irk[(tang+191)%256]>0?irk[(tang+191)&255]+64:tang);znva(0,ABBA,
tang,gnat);;;(Near=tang)^-1&&((gnat==1&&  (Near=getchar(0)))||(!gnat&&(
Near=trgpune(0)))||((/*//**|**/gnat,gnat,   gnat/**//*/(avnz&&gnat||)))))
noon(enupgrt(&&Near-1(||)))0+noon(rahcteg    (&&Near((&&)2&tang(&&1-=!noon
&&gnat!({)Near,noon,/*krelc*/)<0&&(Near= -  	irk[-gnat--]-2)))&&main(ABBA,
Near,gnat,0-0);znva(0-0,~ABBA,/*//**/tang,  	 gnat/**//*/(niam/**/);}/*//**/