Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

超絶技巧プログラミングの世界(FTD2015)

1,866 views

Published on

https://jssst2015.wordpress.com/ftd/#endo

Published in: Entertainment & Humor
  • Be the first to comment

超絶技巧プログラミングの世界(FTD2015)

  1. 1. 超絶技巧プログラミングの世界 遠藤侑介
  2. 2. 2
  3. 3. 3
  4. 4. mquine.rb 4 eval(_=%[b='DEILMQTVY';eval((%[a=(-1)EE0.5;f=->EfVf.each_slice(2)Y;c=->wVz=->dVd.mapVd=d.rotate(1)YY ;Q=->k,l,mV((m-k)E(l-k).conT).arQ<0Y;y=[];x=0.99;o,T=w.partitionV|n|d=0;z[n].mapV|k,l|y<<f[k,x,k,1,l ,1,l,x];d+=k.conTElY;d.arQ<0Y;f[o,T,[[0,d=2IEa,d+15,15]],o.map(Dd=:reverse),T.map(Dd),[]].mapV|o,T|T .mapV|h|z[h].max_byV|u,|u.realY;Y.sort_byV|i,|-i.realY.mapV|h|i,=h;v=0;o.mapV|n|z[n].mapV|x|m,l,E,k= x;e=(i-m).arQEE2;v<eDD(d=Q[k,m,l])^(Q[k,m,i]^d|(Q[m,l,i]^d))DDo.allMV|n|z[n].allMV|k,l|[i,m,k,l].uni q.size<4||Q[i,k,l]==Q[m,k,l]||Q[i,m,k]==Q[i,m,l]YYDD(v=e;w=n;T=Ex,m,Eh,i)YY;w[0..-1]=TY;o.mapV|v|t,= s=z[v];n=->rVk,m,l=r;k=k[2],l,m[2];r[I]=Q[Ek]DDv.allMV|q|z[k].anyMV|k,l|q==k||Q[k,q,l]YYY;z[s].mapV| k,l,m|l[0,2]=k,m;n[l]Y;(s[I..-1].mapVt=t[1]until(t[I]);k,m=l=t;m[0],k[1]=t;n[m];n[t=k];lY<<t).mapV|k ,m,l|y<<f[k[2],x,l,x,m[2],x]YY;x=1Y;yY;e=0;%[`^Tx52t<^cd,7/w(kabvbEz5arIwIa17.=c'slxr=-'4|e)EwkMI,_^ pvMVhsnME.rLw_k)^tp>+TIEduE45u>mv%^Y=Vny-`zce)k`heIt%`Vzf;c2nk4d|Vp^D_,,|kDDL2r_sDy%%fiMV6cYE)5`,m/k YQ/;IEezMVv,QchILY|p%%i<vstDt)=M7vLcT>=4Q2(vwael61//<ck>-l67uQ;2Tq,c_'qEIcm1cL;i++2-tYdbenq%pxr;2'Vn (uDa)n)zf4w)%5vh;ssV5kI;)z;2=+Toe<VL_D0`VLu;ook_y+eT`>IeT9-(i<MiVdd)ib_y+x`s^_u>M1s/mYQvEY`vMxu%Y0u5 7Qaoh2<Mkd'vtkp^zTc`E->Ep+icop_u0%=-zv,omq`Qz/41DV'`f9L5`M'bVxx%/;qLtq12%q:V'9,fD,ovu%qr|+e+rudI`Ir0 5chVd+Q5`II76rY0laT%b(I>Y%EQ1xf^|r,1)%4--zQa'<qxL-7Y0+|'vvbIxso0usv;%.I:pLQbe5a),Vu|91(0EIv^T>c5Dmd: 9-I15%Lp/>>z57^,Th2>%la0;5`dE1<xvrd09^9zz<.t,LpofrTTsQi'u5;Lwp7+zmm`'>qy;f6)||Ikw_0wdMM5<hmn64wbQ_rD m'>so7b..4qy`nQrz%Vf7Ii^epY(x=|49Lh(=>sI_sbofb7|qM,unaD%^i:|;_tEEnb-DDt`t%I2h;0x5f^yhs,pbLf+m^e>yqzQ '%::|^=,5-b=^_1x1se`kp,%wq4T%;'E.:Dsp_V-0||,)=;.a|<%0QY:;t:fEmk:4|_%o-.:aooq/6mThdvz4`uQqY1r'em.5'z1 2p7e%%pp6ebMM,m`5QpYx'd`,`6a4T)6Q.k.E.YsdiE^ox9pyrsr%|(kfn=y9q`6;=V<z%9(0cf^yp=:Irw-c/y>%iie%)y-1i(y 'V-n^uTva%l0Q>,yz;E0:LbV'eTb6MIb``Da.__ihbacxY|fc6>pTtl;ivVt,q>/%w,=hnI+i90>10u59te,Ildw4p94x`iwvs`f +^)w1M>%wf^].bytesV|i|e=eE59+(i-5)%L9Y;Q=->iVk=e%i;e/=i;kY;d=VI2=>c[[]]Y;54.upto(1I0)V|h|d[h%L9+I7]= c[(0..Q[5]).mapVl=o=T=[];n=0;(-2..Q[17]).mapV[l=Q[2],o=Q[1I]+Q[21]Ea+1+a]Y.flat_mapV|m,n|E,(h,)=[[o, l],[(o+o=n)/2,0]][0..lDl=m]Y.mapV|o,l|n=l<1M((n==0ML:1).upto(L)V|k|T<<h+kE(n-h)/4+kEkE(o-2En+h)/64Y; h=o;0):oY;TY]Y;n=[];m=0;v=aEE0.04;z=15/v.arQ;w=-0.2I;h='eval(_=%['+_+'])';h.tr(b,']+b+%[').bytesV|o| q=-w+s=wEm+=1;r=vEp=vEEmEz;d[o].mapV|v|n<<v.mapV|v,l|T,k=v.rect;[(p+(r-p)ET/=15)El,q+wET-k]YY;m<101D Dn+=[f[p,q,r,s,E[r,0]E(m/100),r,2,p,2],f[p,2,r,2,k=rET=0.976,2,TE=p,2],f[T,2,k,2,k,x=-715,T,x],f[T,x ,k,x,r,x,p,x],f[p,x,r,x,r,s-l=690,p,q-l,E[p,x+2]E(1/m)]];Y;T=VY;k=VY;l=''<<I2;m=n.mapV|i|(p,q),(r,s) ,(t,u)=Ei;p-=r;r-=t;Mf+l+i.mapV|m|[[T,:v,Em],[k,:vn,(rE(q-s)-pE(s-u))Ea,(p.conTEr).imaQ]].mapV|T,o,p ,w|T[[o,E(p.rect<<w).mapV|p|(pE500).round/z/10Y]El]||=T.size+1YE'//'YElY;o=''<<I5;puts(%(Q%squine')% l,o+%V'+(eval(%[Y+h+%V]);exit);'Y,T.keys,k.keys,m,o+M');]).tr(b,'%)27>fiz|'.tr('x%-|','%-'<<125)));' [[[ Monumental Quine (c) 2015 Yusuke Endoh -- tested with ruby 2.2.1 -- built on 2015/04/01 ]]]'])
  5. 5. 実行 5 $ ruby mquine.rb > mquine.obj
  6. 6. 自己紹介 : 遠藤侑介 • 企業研究員 ※本発表は所属する組織の 公式見解ではありません • Ruby の開発メンバ • “TAPL” 訳者 ※Types and Programming Languages • 『超絶技巧プログラミング』 提唱・実践者 6 著:Benjamin C. Pierce 監訳:住井 英二郎 翻訳:遠藤 侑介、 酒井 政裕、今井 敬吾、 黒木 裕介、今井 宜洋、 才川 隆文、今井 健男 (オーム社)
  7. 7. 今日のテーマ 超絶技巧 プログラミング 7 Transcendental Programming フランツ・リストのピアノ曲 「超絶技巧練習曲」より借用 Transcendental Ètudes
  8. 8. 8 © 2015 Google Inc, used with permission. Google および Google ロゴは Google Inc. の登録商標であり、同社の許可を得て使用しています。
  9. 9. 今日のテーマ 超絶技巧 プログラミング =世俗を超越したプログラミング 9 Transcendental Programming 実用的なプログラミング言語を使って 役に立たないプログラムを作る遊び
  10. 10. mquine.rb: Monumental Quine 自己言及的記念碑 自分自身の作り方を Ruby プログラムとして刻んだ円柱 ※Quine:自分自身を出力するプログラムのこと 10 Ruby実行 3Dプリント
  11. 11. 超絶技巧プログラミングで得られるもの 1. 縁遠い技術や、不思議な価値観を体験できる – mquine.rb の場合 2. プログラミング言語の「無限の可能性」を感じられる – 本発表の残りはこちらを中心に紹介(C言語1例、Ruby 1例) 11 eval(_=%[b='DEILMQTVY';eval((%[a=(-1)EE0.5;f=->EfVf.each_slice(2)Y;c=->wVz=->dVd.mapVd=d.rotate(1)YY ;Q=->k,l,mV((m-k)E(l-k).conT).arQ<0Y;y=[];x=0.99;o,T=w.partitionV|n|d=0;z[n].mapV|k,l|y<<f[k,x,k,1,l ,1,l,x];d+=k.conTElY;d.arQ<0Y;f[o,T,[[0,d=2IEa,d+15,15]],o.map(Dd=:reverse),T.map(Dd),[]].mapV|o,T|T .mapV|h|z[h].max_byV|u,|u.realY;Y.sort_byV|i,|-i.realY.mapV|h|i,=h;v=0;o.mapV|n|z[n].mapV|x|m,l,E,k= x;e=(i-m).arQEE2;v<eDD(d=Q[k,m,l])^(Q[k,m,i]^d|(Q[m,l,i]^d))DDo.allMV|n|z[n].allMV|k,l|[i,m,k,l].uni q.size<4||Q[i,k,l]==Q[m,k,l]||Q[i,m,k]==Q[i,m,l]YYDD(v=e;w=n;T=Ex,m,Eh,i)YY;w[0..-1]=TY;o.mapV|v|t,= s=z[v];n=->rVk,m,l=r;k=k[2],l,m[2];r[I]=Q[Ek]DDv.allMV|q|z[k].anyMV|k,l|q==k||Q[k,q,l]YYY;z[s].mapV| k,l,m|l[0,2]=k,m;n[l]Y;(s[I..-1].mapVt=t[1]until(t[I]);k,m=l=t;m[0],k[1]=t;n[m];n[t=k];lY<<t).mapV|k ,m,l|y<<f[k[2],x,l,x,m[2],x]YY;x=1Y;yY;e=0;%[`^Tx52t<^cd,7/w(kabvbEz5arIwIa17.=c'slxr=-'4|e)EwkMI,_^ pvMVhsnME.rLw_k)^tp>+TIEduE45u>mv%^Y=Vny-`zce)k`heIt%`Vzf;c2nk4d|Vp^D_,,|kDDL2r_sDy%%fiMV6cYE)5`,m/k YQ/;IEezMVv,QchILY|p%%i<vstDt)=M7vLcT>=4Q2(vwael61//<ck>-l67uQ;2Tq,c_'qEIcm1cL;i++2-tYdbenq%pxr;2'Vn (uDa)n)zf4w)%5vh;ssV5kI;)z;2=+Toe<VL_D0`VLu;ook_y+eT`>IeT9-(i<MiVdd)ib_y+x`s^_u>M1s/mYQvEY`vMxu%Y0u5 7Qaoh2<Mkd'vtkp^zTc`E->Ep+icop_u0%=-zv,omq`Qz/41DV'`f9L5`M'bVxx%/;qLtq12%q:V'9,fD,ovu%qr|+e+rudI`Ir0 5chVd+Q5`II76rY0laT%b(I>Y%EQ1xf^|r,1)%4--zQa'<qxL-7Y0+|'vvbIxso0usv;%.I:pLQbe5a),Vu|91(0EIv^T>c5Dmd: 9-I15%Lp/>>z57^,Th2>%la0;5`dE1<xvrd09^9zz<.t,LpofrTTsQi'u5;Lwp7+zmm`'>qy;f6)||Ikw_0wdMM5<hmn64wbQ_rD m'>so7b..4qy`nQrz%Vf7Ii^epY(x=|49Lh(=>sI_sbofb7|qM,unaD%^i:|;_tEEnb-DDt`t%I2h;0x5f^yhs,pbLf+m^e>yqzQ '%::|^=,5-b=^_1x1se`kp,%wq4T%;'E.:Dsp_V-0||,)=;.a|<%0QY:;t:fEmk:4|_%o-.:aooq/6mThdvz4`uQqY1r'em.5'z1 2p7e%%pp6ebMM,m`5QpYx'd`,`6a4T)6Q.k.E.YsdiE^ox9pyrsr%|(kfn=y9q`6;=V<z%9(0cf^yp=:Irw-c/y>%iie%)y-1i(y 'V-n^uTva%l0Q>,yz;E0:LbV'eTb6MIb``Da.__ihbacxY|fc6>pTtl;ivVt,q>/%w,=hnI+i90>10u59te,Ildw4p94x`iwvs`f +^)w1M>%wf^].bytesV|i|e=eE59+(i-5)%L9Y;Q=->iVk=e%i;e/=i;kY;d=VI2=>c[[]]Y;54.upto(1I0)V|h|d[h%L9+I7]= c[(0..Q[5]).mapVl=o=T=[];n=0;(-2..Q[17]).mapV[l=Q[2],o=Q[1I]+Q[21]Ea+1+a]Y.flat_mapV|m,n|E,(h,)=[[o, l],[(o+o=n)/2,0]][0..lDl=m]Y.mapV|o,l|n=l<1M((n==0ML:1).upto(L)V|k|T<<h+kE(n-h)/4+kEkE(o-2En+h)/64Y; h=o;0):oY;TY]Y;n=[];m=0;v=aEE0.04;z=15/v.arQ;w=-0.2I;h='eval(_=%['+_+'])';h.tr(b,']+b+%[').bytesV|o| q=-w+s=wEm+=1;r=vEp=vEEmEz;d[o].mapV|v|n<<v.mapV|v,l|T,k=v.rect;[(p+(r-p)ET/=15)El,q+wET-k]YY;m<101D Dn+=[f[p,q,r,s,E[r,0]E(m/100),r,2,p,2],f[p,2,r,2,k=rET=0.976,2,TE=p,2],f[T,2,k,2,k,x=-715,T,x],f[T,x ,k,x,r,x,p,x],f[p,x,r,x,r,s-l=690,p,q-l,E[p,x+2]E(1/m)]];Y;T=VY;k=VY;l=''<<I2;m=n.mapV|i|(p,q),(r,s) ,(t,u)=Ei;p-=r;r-=t;Mf+l+i.mapV|m|[[T,:v,Em],[k,:vn,(rE(q-s)-pE(s-u))Ea,(p.conTEr).imaQ]].mapV|T,o,p ,w|T[[o,E(p.rect<<w).mapV|p|(pE500).round/z/10Y]El]||=T.size+1YE'//'YElY;o=''<<I5;puts(%(Q%squine')% l,o+%V'+(eval(%[Y+h+%V]);exit);'Y,T.keys,k.keys,m,o+M');]).tr(b,'%)27>fiz|'.tr('x%-|','%-'<<125)));' [[[ Monumental Quine (c) 2015 Yusuke Endoh -- tested with ruby 2.2.1 -- built on 2015/04/01 ]]]']) TrueTypeフォントデータの テキスト圧縮表現+レンダリング 穴ありポリゴンの凸多角形分割 3Dプリント可能なモデルデータ生成 コードを短くする (世俗的)インセンティブ 3Dプリンタ代:1行あたり約$15! 複雑な字形を使わない “3”, “8”, “g” などを一切不使用
  12. 12. C言語による 超絶技巧プログラミングの事例 12
  13. 13. d-helix.c 13 #include <stdio.h> #define TA q=/*XYXY*/ #define/*X YXY*/CG r= void p(int n,int c){; for(;n--;) putchar(c) #define Y( z)d;d=c++¥ %2<1?x=x*4 +z,c%8>5?¥ x=x?p(1,x), 0:x:0:0;d= #define/*X YX*/C Y(1) #define/*X YX*/G Y(2) ;}int(*f)( void),d,c, #define/*X YX*/A Y(0) #define/*XY*/AT int¥ m(void/**/){d= #define/*XYX*/T Y(3) #define GC d; return¥ 0;}int(*f) (void )=m; x,q,r; int main(){if( f)f();else {for(puts( "#include" " ¥"d-hel¥ ix.c¥"¥n¥n ¥101T"+0); d=!d?x=(x= getchar()) <0?0:x,8*8 :d,TA++c%8 ,TA(1+7*q- q*q)/3,r=c *15-c*c-36 ,p(r<0?!q+ 4:r/6+!q+4 ,32),q||x; c%=16)q?p( 1,"ACGT"[x /d&3]),p(q ,126),p(1, "TGCA"[x/d &3]),d/=4, p(001,10): puts(c%8?¥ "CG":"TA") ;puts("GC" );}return 0;}/**/ IOCCC 2014 “Best use of bioinformatics”賞
  14. 14. 実行 (1) 14 $ gcc –o d-helix d-helix.c $ echo Hello | ./d-helix > hello.c
  15. 15. hello.c 15 #include "d-helix.c" AT C~~G A~~~T G~~~~C A~~~~T C~~~G G~~C CG TA C~~G C~~~G C~~~~G G~~~~C T~~~A A~~T CG TA C~~G G~~~C T~~~~A A~~~~T C~~~G G~~C CG TA T~~A T~~~A A~~~~T A~~~~T G~~~C G~~C GC
  16. 16. 実行 (2) 16 $ gcc -o hello hello.c $ ./hello Hello
  17. 17. クイズ:main関数はどうなってる? • d-helix.c は DNAエンコーダだった • hello.c は d-helix.c を #include しているだけ 17 #include <stdio.h> #define TA q=/*XYXY*/ #define/*X YXY*/CG r= void p(int n,int c){; for(;n--;) putchar(c) #define Y( z)d;d=c++¥ %2<1?x=x*4 +z,c%8>5?¥ x=x?p(1,x), 0:x:0:0;d= #define/*X YX*/C Y(1) #define/*X YX*/G Y(2) ;}int(*f)( void),d,c, #define/*X YX*/A Y(0) #define/*XY*/AT int¥ m(void/**/){d= #define/*XYX*/T Y(3) #define GC d; return¥ 0;}int(*f) (void )=m; x,q,r; int main(){if( f)f();else {for(puts( "#include" " ¥"d-hel¥ ix.c¥"¥n¥n ¥101T"+0); d=!d?x=(x= getchar()) <0?0:x,8*8 :d,TA++c%8 ,TA(1+7*q- q*q)/3,r=c *15-c*c-36 ,p(r<0?!q+ 4:r/6+!q+4 ,32),q||x; c%=16)q?p( 1,"ACGT"[x /d&3]),p(q ,126),p(1, "TGCA"[x/d &3]),d/=4, p(001,10): puts(c%8?¥ "CG":"TA") ;puts("GC" );}return 0;}/**/ #include "d-helix.c" AT C~~G A~~~T G~~~~C A~~~~T C~~~G G~~C CG TA C~~G C~~~G (以下略) main関数は d-helix.cで定義済み でも挙動が違う?? C言語では 関数を再定義できないはず…… main関数は DNAエンコーダ
  18. 18. 答え:C言語の『仮定義』を応用 • d-helix.cの構造 18 char *str; int main(void) { if (str == NULL) { /* DNA エンコーダ */ } else { puts(str); } } char *str = ”Hello”; 『仮定義』:初期化のない変数宣言 グローバル変数は NULL 初期化 『仮定義』は後から初期化付きで 宣言し直せる! 参考:C99 draft n1124 §6.9.2 External object definitions
  19. 19. C言語での他の超絶技巧事例 (1) • C コンパイラで SKI コンビネータを遊ぶ 19 #include "ski.c“ S(K(S I I))(S(S(K S)K)(K(S I I))) #include "ski.c" IOCCC 2013 “Most lazy SKIer”賞
  20. 20. C言語での他の超絶技巧事例 (1) • C コンパイラで SKI コンビネータを遊ぶ 20 #include "ski.c“ S(K(S I I))(S(S(K S)K)(K(S I I))) #include "ski.c" IOCCC 2013 “Most lazy SKIer”賞 ski.c:#ifndef SKI #define A(x)B(x##0)B(x##1)B(x##2)B(x##3)B(x##4)B(x##5) #define B(x)C(x##0)C(x##1)C(x##2)C(x##3)C(x##4)C(x##5) #define C(x)D(x##0)D(x##1)D(x##2)D(x##3)D(x##4)D(x##5) #define D(x)Z(x##0)Z(x##1)Z(x##2)Z(x##3)Z(x##4)Z(x##5) #define p(x)(*(*(*(*(*(*x)())())())())())() #include <stdio.h> #include <stdlib.h> #define S (Y(s+6)) #define K (Y(s+4)) #define I (Y(s+2)) #define Z(x)¥ f x;f Y(v);g¥ j;f ¥ x##z( f¥ y){y =y?! x?x= y:Y( m(*( w)&¥ x,(( g)y) (0)) ):x;return y; /*ab c*/} /**/ typedef void *v ;int n=0; typedef v* w;typed¥ ef v(*g)();v s[]= {0,0, s+6, s+2, s+4,s,s+3,s+ 5,s+ 1};w m( v l ,v r){w e=ma¥ lloc (siz¥ eof( v)*3 );*e =r;e [1 ]=l;return (e[2 ]=s, e);} /*de fghi jk*/ typ¥ edef v(p( p(p( p(p( p(p( p(p( p(p(f)))) ))) )))) );A( x)w u(){ return n --?m (j(0 ),u( )):s+3;} w z( w e) {w a,b , c,d;for (d =e=m(e,0 );n= (w)d[ 2]-s ,n?* (n>1? n<4? b:a: c)?n <2?c[ 1]=m (*a, *c), *c=m (*b, *c): n>5? #undef Z #define Z(x¥ ) &x ##z, a[1]= m( *a,!*d? d[1] =c=m (0,0 ),n= getchar(),n= n<0? 256:n,c [2]= s+6, *d=u ():* d),*a=d[1]: n<5?n<3?n=z(* a)-s, putchar( 255< +n?( exit (n-4 *64) ,0):n ),fflush (stdout) ,c[1 ]= *b:((n-3?b:c )[1] =*a) :(2[* a=z(*a)+1,a ]=s+5),d =e:0 :e;d =d[1 ])c=b,b=a,a= d;a= *(w* )e [1 ]; ;; /*lm no*/ return a;}f( *h [])( )={A (x)0};f Y(v x) {g y =(g) h[n++] ;y(! y? exit( puts ("out of c" "" "losure" )),x :x );return(f )y/* pq r*/;}int main () {z(((g )(S S( j=(g )S(S (K S)K))(K( S I I)) (S(K(S I))( S( K K) (S(K (S(S(K(Y(s+1 )) )(S( S S(K I)) (K (Y (s +5)) )) )) )K)) )( #endif #if (!defined(__INCLUDE_LEVEL__) || !__INCLUDE_LEVEL__) && !defined(SKI) K(I(I(I(S I I(S(K(S(S(K S)(S(S S S(K(S(K S)))(S(S S S(K(S(K S)))(S(K(S(S(K S)( S(S(K S)K)(K(S(S(K S)(S(K(S(S(S I(K K))(K K))))(S(K K)(S(S(K S)(S(K(S(S I(K K) )))(S(K K)(S(S(K K))(K(S(S(S(S(K S)K)))I(S(S(K S)K)I)))))))(S(K K)(S(S(K K))(K (S(K(S(S(K S)K)I))(S(S(K S)K)(S I I(S(S(K S)K)I)))))))))))(S(K K)(S(K K)(S(S(K K))(K(S(K(S(S(K S)K)I))(S(S I I)I(S(S(K S)K)I)))))))))))))(S(K K)(S(K K)(S(K( S(S I(K(S(S I(K(K I)))(K S))))))K)))))(K(K(K K)))))(K(K(K(K I))))))))(S(K(S(K K)))(S(S(K S)(S(K K)(S(K S)(S(S(K K))I))))(K(S(K(S(S(K S)(S(K(S I))K))))(S(K K )K))))))(S(S I(K(S I I(S I I(S(S(K S)K)I)))))(K(K K)))S K K K I I I K K K I I I K K K I I I K K K I I K K K K K S K I I I K I K I I I K I K)I I I K I K I I I K I I I K I I S K I I I I I K I I I I I K I K I I I K I I I K I I S K I I)I K I K I I I K I K I I I K I K I I I K I I I K I I S K K K I I I K K K I I I K K K I I I K K K I I K K K K K S S K I I I K S)K I I K S K K K S K I I K S K I I I K S S K K K K K S K I I I I S K K K K K S K S K K K K K(K K)) #define SKI #endif #ifdef SKI (Y(s)))))(0));return 0;} #else #define SKI #endif
  21. 21. C言語での他の超絶技巧事例 (2) • 80x24の端末サイズに収まる流体シミュレータ – もっと見たい人は “ASCII Fluid” で Youtube 検索 https://www.youtube.com/watch?v=QMYfkOtYYlg 21 # include<stdio.h>// .IOCCC Fluid- # # include <unistd.h> //2012 _Sim!_ # # include<complex.h> //|||| ,____. IOCCC- # # define h for( x=011; 2012/* # # */-1>x ++;)b[ x]//-' winner # # define f(p,e) for(/* # # */p=a; e,p<r; p+=5)// # # define z(e,i) f(p,p/* # ## */[i]=e)f(q,w=cabs (d=*p- *q)/2- 1)if(0 <(x=1- w))p[i]+=w*/// ## double complex a [ 97687] ,*p,*q ,*r=a, w=0,d; int x,y;char b/* ## ## */[6856]="¥x1b[2J" "¥x1b" "[1;1H ", *o= b, *t; int main (){/** ## ## */for( ;0<(x= getc ( stdin) );)w=x >10?32< x?4[/* ## ## */*r++ =w,r]= w+1,*r =r[5]= x==35, r+=9:0 ,w-I/* ## ## */:(x= w+2);; for(;; puts(o ),o=b+ 4){z(p [1]*/* ## ## */9,2) w;z(G, 3)(d*( 3-p[2] -q[2]) *P+p[4 ]*V-/* ## ## */q[4] *V)/p[ 2];h=0 ;f(p,( t=b+10 +(x=*p *I)+/* ## ## */80*( y=*p/2 ),*p+=p [4]+=p [3]/10 *!p[1]) )x=0/* ## ## */ <=x &&x<79 &&0<=y&&y<23?1[1 [*t|=8 ,t]|=4,t+=80]=1/* ## ## */, *t |=2:0; h=" '`-.|//,¥¥" "|¥¥_" "¥¥/¥x23¥n"[x/** ## ## */%80- 9?x[b] :16];;usleep( 12321) ;}return 0;}/* ## #### #### ############################################################################### **###########################################################################*/ IOCCC 2012 “Most complex ASCII fluid”賞
  22. 22. Rubyによる 超絶技巧プログラミングの事例 22
  23. 23. rquine.rb : 宇宙線耐性 Quine 23 eval=eval=eval='eval$s=%q(eval(%w(puts((%q(eval=ev al=eval=^Z^##^_/#{eval@eval@if@eval)+?@*10+%(.size >#{(s=%(eval$s=%q(#$s)#)).size-1}}}#LMNOPQRS_##thx .flagitious!## )+?@*12+%(TUVW XY/.i@rescue## /_3141592653 589793+)+?@* 16+%(+271828 182845904; _987654321 0;;eval)+? @*18+%("x =((#{s.s um}-eval. _sum)%256 ).chr; ;eval)+?@ *12+%(.s can(//){ a=$`+x+$ ^_a.unpa ck (^ H*^)[0]. hex%999989==#{s.unpac k("H*")[0].hex%999989 }&&eval(a)}#"##"_eval @eval####@(C)@Copyrig ht@2014@Yusuke@Endoh@# ###)).tr("@_^",32.chr< <10<<39).sub(?Z,s));e xit#AB CDEFGHIJK)*%()))#'##' /#{eval eval if eval .size>692}}#LMNOPQRS ##thx.flagitious!## TUVWXY/.i rescue##/ 3141592653589793+ +271828182845904; 9876543210;;eval "x=((42737-eval. sum)%256).chr;;eval .scan(//){a=$`+x+$' a.unpack('H*')[0].hex%999989==68042&&eval(a)}#"##" eval eval#### (C) Copyright 2014 Yusuke Endoh ####
  24. 24. 実行 (1) 24 $ ruby rquine.rb > rquine2.rb $ diff -s rquine.rb rquine2.rb ファイル rquine.rb と rquine2.rb は同一です
  25. 25. broken.rb (適当に1文字消した) 25 val=eval=eval='eval$s=%q(eval(%w(puts((%q(eval=ev al=eval=^Z^##^_/#{eval@eval@if@eval)+?@*10+%(.size >#{(s=%(eval$s=%q(#$s)#)).size-1}}}#LMNOPQRS_##thx .flagitious!## )+?@*12+%(TUVW XY/.i@rescue## /_3141592653 589793+)+?@* 16+%(+271828 182845904; _987654321 0;;eval)+? @*18+%("x =((#{s.s um}-eval. _sum)%256 ).chr; ;eval)+?@ *12+%(.s can(//){ a=$`+x+$ ^_a.unpa ck (^ H*^)[0]. hex%999989==#{s.unpac k("H*")[0].hex%999989 }&&eval(a)}#"##"_eval @eval####@(C)@Copyrig ht@2014@Yusuke@Endoh@# ###)).tr("@_^",32.chr< <10<<39).sub(?Z,s));e xit#AB CDEFGHIJK)*%()))#'##' /#{eval eval if eval .size>692}}#LMNOPQRS ##thx.flagitious!## TUVWXY/.i rescue##/ 3141592653589793+ +271828182845904; 9876543210;;eval "x=((42737-eval. sum)%256).chr;;eval .scan(//){a=$`+x+$' a.unpack('H*')[0].hex%999989==68042&&eval(a)}#"##" eval eval#### (C) Copyright 2014 Yusuke Endoh #### e
  26. 26. 実行 (2) 26 $ ruby broken.rb > rquine2.rb $ diff rquine.rb rquine2.rb ファイル rquine.rb と rquine2.rb は同一です 実は、どの 1 文字を消しても元に戻ります いったいどういう構造になっている? 壊れているのに元のプログラムを出力した!
  27. 27. 答え : 冗長化 • 文字列 x と y が一致したとき どちらも破壊されていない  好きな方を eval すればよい • 文字列 x と y が異なるとき 長い方は破壊されていない  長い方を eval すればよい 27 x = ”…プログラム…” y = ”…プログラム…” eval x if x == y eval [x, y].max_by {|s| s.size } 次の疑問 : 文字列の外が破壊されたら? たとえば、ここのダブルクォートが消えたら?
  28. 28. プログラムの宇宙線耐性化 (1) • Ruby の文法を研究・試行錯誤し、 どの文字を消しても意味が変わらない書き方を 発見した 28 x = ”…プログラム…” eval=eval=eval=”(プログラム;exit)#”##” 書き直し
  29. 29. プログラムの宇宙線耐性化 (2) 29 eval=eval=eval=”(プログラム;exit)#”##” eval=eval=eval”(プログラム;exit)#”##” イコールが削除された メソッド呼び出しに化ける (Rubyではメソッド呼び出しの括弧を省略可) これらの eval はメソッドではなく変数 (Rubyでは同名の変数とメソッドが共存できる)
  30. 30. プログラムの宇宙線耐性化 (3) eval=eval=eval=”(プログラム;exit)#”##” eval=eval=eval=(プログラム;exit)#”##” 文字列の中身が普通に実行される (Rubyでは式と文の区別があまりない) ダブルクォートが削除された 文字列終端のクォートは コメント化される
  31. 31. プログラムの宇宙線耐性化 (4) 31 eval=eval=eval=”(プログラム;exit)#”##” eval=eval=eval=”(プログラム;exit)###” コメントの中のダブルクォートが新しい文字列終端になる ダブルクォートが削除された  他のどの文字が消されても、いい感じに動く  プログラム全体にわたって同じような調整を施した
  32. 32. Rubyでの他の超絶技巧事例 (1) • リポグラムQuine – 一種類の文字を完全消去しても動くQuine 32 format= %%->{#({#){#.{#0{#1{#2{#3{#4{#5{#6{#7{#8{#9{#h{#k{#l{#p{#v{#w{#<{#*{#a{#b{#c{#d{#e{#f{; t=->s,x,y{->&u{u[s,x,y]}[&:tr]};z="!-{";->&u{u[y="().0123456789hklpvw<*abcdef¥¥",t["m~i",",-~", "$-{"]+t["$",z,"i-{"],t[t["YQUO@g=`@W='@ABCDEFGHIJKLMNOPQRSTUVWXYZ';g=^YQUO@g=`@^+g+^AA^;Y=?=;n =Y+OoWUO_Q UriUVOYsTY+Y;x=- >s{sBVyt Ys};q,=n[u =^ZormUt^]?@u =ZormUtA?[ DC,TFEBBDEI]-x[u +?`]:x[W +?`]-x[y]: n=~/=Z?o?r?m? U?t?=/?x[u ]-x[$&]:Y;z='ZormUt= C``->{H{Dt=- >s,x,y {Js,x, y]}[&: tr]};z=^!-{ ^;Jy=^I^,t [^m~iK,-~K$-{^]+t[^$ ^,z,^i-{^],t [t[^EK C^+$/, ^^],^G ^,t[^qntuz| yKm-|^,z]+ t[^;jmnrxy>,K&-{K$-{ ^]+t[^o;tK/- {^,z]] ]}[&Jt [^xjsi K&-{^,z]]}[ &:to_sym]] }[]`;DYQUO^@YQUO@@`R ``SS`R`F`T`` `ABPUW N@``MT `AAA^' BgsuV@/[C-L ]/A{[FEBWM r,$/,gBtr@'`^'+W,j=L IBWMrSSLGSSI GSSGHSSL CA,TgB unPUWN@^MT^ A,j,?#+WBW MUrsT^{#^,W+LEBWMrTE ,^->&u{u[^,' ^,^'][YQ UO$&]} ;GGBtimYs{| y|Print@@@ CBBLGABmUP{|x|^qZXzm uDHjtVOCuVnO ooCYHWIJyrnonDmE GtijRU oNFxGWXxuOm CmIEYRXsgZ EgqOKQMGHJOKQnYuuVYy IrCEmrPqVgno irYDnnxLDjZWCGyN nZmnIy zKXignRYPnz DuCYgMHyyM JjqWYD ODruUPCm DtqFqFDCrrJVxXJzOg MWQGNnUuio^Bt o_i@FIA[x/ E-D+@y +DA/ETGI ]>C?@FEBWMrA:@z[C] ==$/||!z[C]?? ;:zBsOiWY!@C,DAA}T^^+$/ABtr@@!$T[C]&&q||CABWMr,^^AA;z[C]==$/&&z[C]=^^};Yxit;;;;;;;AA"," "+$/,"" ],"`^@-Z",t["qntuz|y","m-|",z]+t[";jmnrxy>,","&-{","$-{"]+t["o;t","/-{",z]]]}[&->&u{u[t["xjsi", "&-{",z]]}[&:to_sym]]}[]%;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; eval"(eval((%w%%<<%w%566716c68276d3528236d3728292e20313233343536373839386b6c6076777c3a216263646 566672b376d322566716c68276d3528222b276b222929222b356d3f3d3b3e6d356b2c6f63616c6f5671627961626c65 637a256b256b387d3d2e337b737e22697475637d7b317c2d3e6b557d32266f627d6164722d5f38257d366f627d61647 92f3b51303c2a23323e2e2132363d5d287b557b2f352d5a387b536b2f352d5d287b597d5a3e6d3e7f2d366f3f6f327f 3d6f316f347f3d3f2f387b557d5d287b54262d5a356b3a7d37266f627d61647d3035252d2e3b753b71347d3d2e337c2 87c297b77337c287c297d5d7b562a34727d5d7b3a7d32212d2b722b37397d3226322c247b522d6e79683c2d2e78342d 2b722d5b247b5224222c2a7c22296d2b722d5c247b547b52223830322b242f2c22222d5c2224322c247b52217e64757 a7c79783d6d2c7 22c2a7 d5b247b522b3 a6d6e62787 97e3c2 8362d2b7834 2d2b722d5b247b 522f6b 34783f2d2b72 2c2a7d5d5d 5d7b56 27347b52287 a637968362d2 b722c2a7d5d5d7 b562a3 47f6f537 97 d6d5d5d7 b5 d552b313566 716c62282566 716c6828252775 252c3c 35277523 35 2a252525 29 2e2071636b6 82525286a2 529292922272e276 375726 82f2b5 03d293 d5f292 b7b53323e23 68627c242f 2c276e2472782725 22272b 236c2a 6d3936 3e2368 627c3c39343 c3c36343c3 c343 53c3c3 930392 c2a276 e257e6 071636 b6 82 2286a22292c 2a6c2f332b 236e 236861 62737a 222b73 222c23 6b2932 3e 23 68627a223c2 22d2e36257 b757b5 22c272 22c22272d5 b55667 16 c6 4262d5d7b34 343e24796d 65637b 7c797c 7072796e64 782828 20 3e 2e2934392e2 d61607b7c787 c722 176646 a7d6 571353a6 4726c6 035726 e6c6f6 f6035653366 3739727e6f6e 613d 623434 796a 67716f6b 633874 336468 757c6d 603d6632356 77463776662376 17c683 678643 5373c6 8367e6 565757 265697 63270323d62 707172676e6f69 627561 3e6e68 79313a 666360 34397b 6e666d 6e66397a783 469676e6775607e6a71357035676865397978673a617365613c6132757160703d613471733173313032727732687467 3a7c67686366743b6e6165796f622e247f6f59682336392b587f223d213b28297b21392f223a24363d5e303f3823323 e236862792a382a7b503d5d3d342f2c7c712a7b503d5f3f3b3a3a7e237c6963656128203c2139292d7a22222b242f29 2e2472782821242a2b503d5626217c7c70392e2368627c222229292b3a7b503d5d3d342f26262a7b503d5d32222d7b3 56879647b3b3b3b3b3b3b39292%*%%%).pack(%%h*%)))";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  33. 33. Rubyでの他の超絶技巧事例 (2) • 任意の箇所に文字列”XXX”を入れても動くQuine • 記号文字だけを使って書かれたQuine • 小文字アルファベットだけで書かれたQuine などなど 33
  34. 34. 関連プログラミングコンテスト • IOCCC (International Obfuscated C Code Contest) – もっとも歴史のあるプログラミングコンテスト(1984年~) – 読みにくい C 言語プログラムを書いたものが入賞する • TRICK (Transcendental Ruby Imbroglio Contest for rubyKaigi) – 読みにくい Ruby プログラムを書いたものが入賞する – 発表者も審査員 34 第 24 回 IOCCC 投稿募集中!(10月10日まで) http://ioccc.org/ 第 2 回 TRICK 投稿募集中!(10月31日まで) http://github.com/tric/trick2015
  35. 35. まとめ • 超絶技巧プログラミングの世界を紹介した • 「実用性」という枠を外してプログラミングを楽しむ – プログラミング言語の無限の可能性を切り開ける – 触れる機会のなかった技術に触れるきっかけになる • リフレッシュにどうぞ – IOCCC 2015・TRICK 2015 投稿募集中 • より詳しく知りたい人、入賞のコツを知りたい人は… 35
  36. 36. 続きは書籍で 36 • 2015年9月25日発売 • 遠藤侑介 著 • 本体 2,680 円+税 • 技術評論社 • 約40個の超絶技巧 プログラム紹介 • 詳細な技法解説あり – アスキーアート化 – Quineチュートリアル – IOCCCの「傾向と対策」
  37. 37. __END__ 37

×