The 22nd IOCCC: Most recyclable のエントリ
/*@@@sssss8]][[[[a#@@sss0['w}8|v}a<{av}a@{av}j>~{v}j8|c[sa?|{8[|#~} [j#@ra>~}sa!{>}|#r0l}sao8}[a'f8|r'8[j?x[?@<[j?@[j?@[s?>|;[[[j!>b'8'a@<cb@>? c$kg_@<b#0pf<#keab{_b0|c0#d#0#|'o{i<!8dr,f_{#rg{baiderh{er0}|'{0{ic.df?'o|j{lim 0'{i?#c0b|c#kg!}r!8lp1g!|i_ar<[#0g|h_}ieg>|_ah|sr<|i[[[}s#f@}[{@u~~~r@[|#|{ssss{a }|0~{?}|<{?}|qj?}s@[_}j0]][[[[a_@@@sssss<[[?>=sln5+a[so#,g-0aw;#*a>*abwa.*+da9=n?<6 -'7%71>e_?>a[j;e=;scdet?>shd??a;5&6:=[ch@aw[sf;[#<[[j>k7__?>>d>==n'6+7*abcdnh3a_jhw b6;73;b#<ww<7bcw7d+;&i=cn?c>=#d5;8w3;nawn#<;;77__ra?8hi1abcww#>==<[;k7[wn7[=,>ab[a@s[ ='b,.[8.?>>fdjn(_2$a8c8[[j_8.=B6+b8]]]]]]]]]j1;7_sj<[[af;7sjd][j_<7!=a>d7_j8d.ab[hybm ?>=;ei7aws1d!ebn _,?>0aka[#;5+7 !?ac;7_wa7{;a3_ bjcna>a<;bs8;7 j-=cabh?97_sj[' -5*j[!;5+a7[1wb[!wBb7w?0wb _?an+&e_|j'4a<7 0v;7d.kd8wa?.=:a-wwm=:;[e5 *-=fwn7rab[c.j# eaw#c>>>bml;mtdekssae zqtd[39<u_char* p=$,w[13997],*h=w, *q,*r_****_;#in clude_*ioccc*2 013*_<stdio.h>_ *--2013-ioc cc-2013-ioccc-2 013-- *_#define @n(d);c ((d)> >8);c ( d );*B= 32;B[ y=1]=22 .627400; B[2]=16;_*-i occc-2013 -ioccc -2013-io ccc-201 *_int@a,b,d,e,s,t ,g,z,y;double@f, B[3],i,j,k,l;void @m(int@z){f or(j=k= l=y=1;y<99;y+=2+0) l*=z*z* .038553 ,k*=-y*(y+1),j+=l_ k;i*=j;}int@c( int@d){ return@ putchar (d)_255; }intmain (){for( ;*p;p++ )*p<33?0:(*h++=*p -32);q= h;for(p =w;p<w +823;p++)for(d=*p-56 ,e=-1+ 0;++e<( d<00?5:d<6?d>4?160:30 :d>35?2 7<<(d-3 6):d_9* 6);q++)*q=d<0?*p>>e& 1:d<6|| q[d>35? -108:d%9*-12-12];for(q=h ;g++<61 56;q++)* q?*q=*p- 4?e=*p+ +,e-32?e:0:r&&*r?g %108<2?2:*r++:(r=r?p++:w, 2):0;n( g=8*8187)n(g+8)n(1 6)n(19014)n(18758) ;for(;s<10;s++)c( s<3?s:0)n(g+3)n (67)for (;t<65;)c(t++>0) n(g-24)n(11)c(8 )n(612)n(656)n( 257)n(4352)n(g+ 0-20)n( 5*42);; for(;y ++<207;)c( y<3 1?y<19? y>6:30-y:y<47?y <32||y>36? 16:0:y< 48?2:y%1 6*16+13- y_16)n(64*960)n (g+5)n(4)n( 1)n(g+2 )n(8)n(257)n(0)n( 2*8064)for(;b<4 04096;b++ ){e=32< a?63-a:a;for(f =d=t=s=0;e>t;)e -=++t;e=t%2?e:t -e;;;for(d=a>3 1?e=7-e,14-t-e: t-e;s<64;t=f-= i*B[!d+!e])z=b_ 64%82*8+s_8-4, y=b_5248*8+s%8+7 ,i=z<0||z>647|| y%11>9?1:q[h[z_6+y_11*108]*60+y%11*6+z%6]*2-1,m(s_8*2*d+d),m(s++%8*2*e+e);s=2+t*t;;fo r(d=2;s>3;s_=4)d*=2;;s=8<<(a?12:9);s-=d*2<<!!a*4;s|=t>0?t:t-1+d;c(s_256)?c(0):0;c(s)? c(0):0;if(a++>62){n(g-8+b_64%8)a=0;}}n(g+1)return@0+0;}*/ /*IOCCC*/#include<stdio.h> char*p,w[13997],*h=w,*q,*r;int d,e,g;int main(){for(;e<3583;e++>15&&e<3582&&d>32?*h ++=d-95?d:47:0)d=getchar();q=h;for(p=w;p<w+823;p++)for(d=*p-88,e=-1;++e<(d<0?5:d< 6?d>4?160:30:d>35?27<<(d-36):d/9*6);q++)*q=d<0?*p>>e&1:d<6||q[d>35?-108:d%9*-12 -12];for(q=h+108;g++<5995;)putchar(g%109<1?10:*q++?*p-36?e=*p++,e-64?e:32:r /*IOCCC2013*/&&*r?g%109%108<2?34:*r++:(r=r?p++:w,34):32);return 0;}
使い方
まず普通にコンパイルし、以下のように実行します。
$ gcc -o endoh2 endoh2.c $ ./endoh2 < endoh2.c > jpeg.c
すると本番のプログラムが出てきます。
char*p="@@@sssss8]][[[[a#@@sss0['w}8|v}a<{av}a@{av}j>~{v}j8|c[sa?|{8[|#~}[j#@ra>~}sa!{>}|#r0l}sao8}[a'f8|r'" "8[j?x[?@<[j?@[j?@[s?>|;[[[j!>b'8'a@<cb@>?c$kg/@<b#0pf<#keab{/b0|c0#d#0#|'o{i<!8dr,f/{#rg{baiderh{er0}|'{0{" "ic.df?'o|j{lim0'{i?#c0b|c#kg!}r!8lp1g!|i/ar<[#0g|h/}ieg>|/ah|sr<|i[[[}s#f@}[{@u~~~r@[|#|{ssss{a}|0~{?}|<{?" "}|qj?}s@[/}j0]][[[[a/@@@sssss<[[?>=sln5+a[so#,g-0aw;#*a>*abwa.*+da9=n?<6-'7%71>e/?>a[j;e=;scdet?>shd??a;5&" "6:=[ch@aw[sf;[#<[ [j>k7//?>>d>==n'6+" "7*abcdnh3a/jhw b6;73;b#<ww<7bc" "w7d+;&i=cn?c >=#d5;8w3;nawn" "#<;;77//ra? 8hi1abcww#>=" "=<[;k7[wn7 [=,>ab[a@s[" "='b,.[8.?> >fdjn(/2$a8" "c8[[j/8.= B6+b8]]]]]" "]]]]j1;7/ sj<[[af;7sjd][j/<7!=a>d7/j8d.ab[hybm?>=;ei7aws1d!ebn/,?>0ak a[#;5+7!?a" "c;7/wa7{; a3/bjcna>a<;bs8;7j-=cabh?97/sj['-5*j[!;5+a7[1wb[!wBb7w?0wb/?a n+&e/|j'4a" "<70v;7d.k d8wa?.=:a-wwm=:;[e5*-=fwn7rab[c.j#eaw#c>>>bml;mtdekssaezqtd[3 9<u/char*p" "=$,w[1399 7],*h=w,*q,*r/****/;#include/*ioccc*2013*/<stdio.h>/*- -20" "13-ioccc- 2013-ioccc-2013--*/#define@n(d);c((d)>>8);c(d);*B=32;B [y=" "1]=22.627 400;B[2]=16;/*-ioccc-2013-ioccc-2013-ioccc-201*/int@a,b, d,e,s" ",t,g,z,y; double@f,B[3],i,j,k,l;void@m(int@z){for(j=k=l=y=1;y<99;y+= 2+0)l*=" "z*z*.0385 53,k*=-y*(y+1),j+=l/k;i*=j;}int@c(int@d){return@putchar(d)/2 55;}int@m" "ain(){;;f or(;*p;p++)*p<33?0:(*h++=*p-32);q=h;for(p=w;p<w+823;p++)for(d= *p-56,e=-1;" "++e<(d<0? 5:d<6?d>4 ?160:30:d>35?27<<(d-36):d/9*6);q++)*q=d<0?*p>>e&1 :d<6||q[d>35" "?-108:d%9*-12-12];for(q=h;g++< 6156;q++)*q?*q=*p-4?e=*p++,e-32?e:0:r&&*r?g%108<2? 2:*r++:(r=r?p+" "+:w,2):0;n(g=8*8187)n(g+8)n(16) n(19014)n(18758);for(;s<10;s++)c(s<3?s:0)n(g+3)n(67)f or(;t<65;)c(t++>" "0)n(g-24)n(11)c (8)n(612)n(656)n(257)n(4352)n(g+0-20)n(5*42);;for(;y++<207;)c(y<31?y<19?y>6:30-y:y<47?y<32" "||y>36?16:0:y <48?2:y%16*16 +13-y / 16)n(64*9 60)n(g+5) n (4)n(" "1)n(g+2)n(8 )n(257)n(0) n(2* 8064) for(; b<404" "096;b++){e =32<a?63- a:a; for (f=d =t= s=0;e" ">t;e-=++ t);e=t%2 ?e:t -e;; ;f or(d =a >31? e=7-e" ",14-t-e :t-e;s <64; t=f-= i* B[ !d+!e ])z=b" "/64%8 2*8+ s/8- 4,y=b /5 24 8*8+s %8+7," "i=z <0| |z>6 47|| y%1 1>9?1:q[h[z/6+ y/11*" "108 ]* 60+y %11 *6+z %6]*2" "-1,m(s/8* 2*d+d),m (s++ %8*2*e +e);s=2 +t*t;" ";for(d=2; s>3;s/=4 )d*= 2 ;;s=8<<(a? 12:9); s-=d*2<< !!a*4" ";s|=t>0?t :t-1+ d;c( s/256)?c(0):0;c(s)?c(0):0;if(a++>62 ){n (g-8+" "b/64%8)a= 0;}} n(g+ 1)return@0+0;}",w[13997],*h=w,*q,*r /****/; #include/* ioccc *2013 */<stdio.h>/*--2013-ioccc-2013-ioccc- 2013--*/ #define n( d);c((d)>>8);c(d);*B=32;B[y=1]=22.627400;B[2]=16;/*-ioccc-2013-ioccc-2013-ioccc-201*/ int a,b,d, e,s,t,g,z,y;double f,B[3],i,j,k,l;void m(int z){for(j=k=l=y=1 ;y<99;y+=2 +0)l*=z*z* .038553,k*=-y*(y+1),j+=l/k;i*=j;}int c(int d){return putchar( d)/255;}int main(){;; for(;*p;p++)*p<33?0:(*h++=*p-32);q=h;for(p=w;p<w+823;p++)for( d=*p-56,e=- 1;++e<(d<0 ?5:d<6?d>4?160:30:d>35?27<<(d-36):d/9*6);q++)*q=d<0?*p>>e&1:d <6||q[d>35? -108:d%9*- 12-12];for(q=h;g++<6156;q++)*q?*q=*p-4?e=*p++,e-32?e:0:r&&*r? g%108<2?2:* r++:(r=r?p ++:w,2):0;n(g=8*8187)n(g+8)n(16)n(19014)n(18758);for(;s<10; s++)c(s<3?s :0)n(g+3)n (67)for(;t< 65;)c(t++>0 )n(g-24)n(11 )c(8)n(612) n(656)n(257) n(4352)n(g+0 -20)n(5*42);; for(;y++<207; )c(y<31?y<19?y >6:30-y:y<47?y< 32||y>36?16:0:y< 48?2:y%16*16+13-y/ 16)n(64*960)n(g+5)n (4)n(1)n(g+2)n(8)n(257)n(0)n(2*8064)for(;b<404096;b++){e=32<a?63-a:a;for(f=d=t=s=0;e>t;e-=++t);e=t%2?e:t-e;; ;for(d=a>31?e=7-e,14-t-e:t-e;s<64;t=f-=i*B[!d+!e])z=b/64%82*8+s/8-4,y=b/5248*8+s%8+7,i=z<0||z>647||y%11>9?1: q[h[z/6+y/11*108]*60+y%11*6+z%6]*2-1,m(s/8*2*d+d),m(s++%8*2*e+e);s=2+t*t;;for(d=2;s>3;s/=4)d*=2;;s=8<<(a?12: 9);s-=d*2<<!!a*4;s|=t>0?t:t-1+d;c(s/256)?c(0):0;c(s)?c(0):0;if(a++>62){n(g-8+b/64%8)a=0;}}n(g+1)return 0+0;}
これをまた実行すると
$ gcc -o jpeg jpeg.c $ ./jpeg > jpeg.jpg
以下のような jpg 画像が出てきます。
それだけ。
解説
一応、現時点で世界最小の jpeg エンコーダじゃないかと思います。jpeg ってヘッダに色々書かないと行けないし、ジグザグスキャンとか離散コサイン変換とかハフマンエンコーディングとかやることが多くて大変なんです。
それでもサイズ制限を完全にオーバーしたので、チート気味に回避してます。というのは、今回初めてサイズチェッカが審査員から提供されたのですが、それが微妙にバグってた (ルール上はコメント含めて 2KB なのに、チェッカはコメント含めず 2KB になってた) ので、本番プログラムをコメントに埋めて、最初のプログラムはコメントをデコードする感じ。(ちなみに、IOCCC ではチートが推奨されてます)
あと、jpeg のハフマンエンコーディングもチートしていて*1、生成される jpeg ファイルは同等な PBM ファイルの 16.4 倍もでかい。(審査員調べ)
一応、正統派の圧縮もがんばっていて、たとえばフォントと形状データには LZ77 風の圧縮をかけてます。
狙いと戦略
1 つくらい Quine ネタをやるかー、と思って作りました。しかし特にひねりがなく、ネタのわりに超巨大。
記念受験のつもりで送ったら意外にも通りましたが、正直あんまし満足な出来じゃないです。次回はもうちょっと頑張りたい。
*1:ビット処理したくなかったので、コードがバイトにアラインするように巧妙に作ったハフマンテーブルを定義してる。圧縮効果は全くない。