3099. Super Quine

 Challenge問題。入力は-10から10の間の整数で、その整数回ぶんだけ自分自身のソースコードを出力する。負の場合は逆順で出力。評価はゴルフ*1。言語はC C99 strict C++ PAS gpc PAS fpc JAVA C#に制限されてる。
 一回だけ自己印刷するようなプログラムなら以下のようなCプログラムが有名。

main(a){printf(a,34,a="main(a){printf(a,34,a=%c%s%c,34);}",34);}
char*f="char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c";main(){printf(f,34,f,34,10);}

 複数回、しかも逆順もありうるというのがこの問題の肝。けど基本的な戦略は上のコードと同じ。直接標準出力にprintfするのでなく、配列にsprintfして、逆順なら後ろから出力するとか。
 多少頑張ったすえ295バイトになった。トップの247バイトは一体何をしてるんだw。今のところ見当がつかない。以下ソースコード(一行なので見苦しいが勘弁)。

char*c="char*c=%c%s%c,u[999];main(n,i,j){n=atoi(gets(&n));sprintf(u+1,c,34,c,34,10);for(j=n<0?1:-1;n;n+=j)for(i=n>0?1:295;u[i];putchar(u[i]),i-=j);exit(0);}%c",u[999];main(n,i,j){n=atoi(gets(&n));sprintf(u+1,c,34,c,34,10);for(j=n<0?1:-1;n;n+=j)for(i=n>0?1:295;u[i];putchar(u[i]),i-=j);exit(0);}

 まだ改良の余地はありそう。特にexit(0);。こいつが16バイトも使ってる。プログラムは0を返さなきゃならないんで(そうしないとエラーになる)入れてるんだけど。exit(0)を使わずに0を返す方法がありそうな。後、出力部分(二重for文)、u[999]の部分とか。

*1:ソースコードの短さ(バイト数)を競うもの