SlideShare uma empresa Scribd logo
1 de 34
Baixar para ler offline
Ruby による超絶技巧プログラミング

 遠藤侑介
宣伝: 翻訳本買ってください
抽象によるソフトウェア設計(Daniel Jackson 著)
 – 中島震 監訳 ・ 今井健男・酒井政裕・遠藤侑介・片岡欣夫 共訳 (オーム社)
 – 会場で買えます!
                             Types and Programming
                              Languages (通称 TAPL)
                              – Benjamin C. Pierce 著
                              – 絶賛翻訳中!




                                                       2
目次
• 背景: 近年のプログラミングの問題
• 提案: 超絶技巧プログラミング
• 実践
 テーマ1: self-descriptive な Ruby プログラム
 テーマ2: 文字を制限された Ruby プログラム

• まとめ



                                       3
近年のプログラミングの問題
• 俗世の欲にまみれすぎ
 – 例: プログラミング言語 Ruby の宣伝文句


       生産性が10倍!       10分でblogが
                        作れる!

           プログラミングが
           楽しくなる!




実用性なんか無くてもプログラミングは楽しい!
                             ※個人の感想です
                                        4
提案: 超絶技巧プログラミング
• 実用性を無視して美しいプログラムを書く行為
    – 普通のプログラミング                     puts “Hello, world!”

    – 超絶技巧プログラミング




                                  
                              alias|send¥
                        ;$stdin=GC | "%p?"%def#
                  FALSE.gets();(8 | 64).chr+232424.
            to_s(25)+", "+%w|w !   |   *"orlc". next<<012||
      (c).Yusuke end;"oh, 2009"    |    "stegano-X."[0,4].reverse
d,be="whydoes","crypto";:make.     |     %.mains..tr'eams',be.delete(d)



• 由来: 超絶技巧練習曲 Transcendental Études (Liszt [1826])
    – Transcendental: 「肉体・精神・魂のすべてを超越する」
                                       http://ja.wikipedia.org/wiki/超絶技巧練習曲

                                                                          5
超絶技巧プログラミングの実践


テーマ 1: self-descriptive な Ruby プログラム



テーマ 2: 文字を制限した Ruby プログラム




                                       6
例題: FizzBuzz
 • 数字を 1 から順に出力する、ただし
   – 3 で割り切れる場合は "Fizz"
   – 5 で割り切れる場合は "Buzz"
   – 両方で割り切れる場合は "FizzBuzz" を出力する
 • 普通の Ruby プログラミングで FizzBuzz
    n = 1
    while true
      case
      when n % 15 == 0 then puts "FizzBuzz"
      when n % 3 == 0 then puts "Fizz"
      when n % 5 == 0 then puts "Buzz"
      else                  puts n
      end
      n += 1
    end                                       7
self-descriptive FizzBuzz
                       eval(s=s=
                       %w@proc{|
                       n|z=32.ch
                       r;k="[#{n
                       +=1}]";u=
              ":>==;<==?"[m=n**4
              %-15,m+13]||"#{$f=
              k}";d="Y.E.#{c=64.
              chr}*'')";$f||d<<z
              +k;t="eval(s=s=%w#
                       {c+s=s[0,
                       334]}#$f#
                       ";25.time
                       s{|y|m=u.
                       bytes.map
                       {|v|t<<s;
                       (0..[62-v
                       ,2].min).
                       map{|x|"i
                       f0zgl11p0
              zghuhku744d8hzeg41qtfx7xs7t
              wflr".to_i(36)[x+32+v*3-y/5
              *44]<1?z*9:t.slice!(0,9)}<<
              z}.join.rstrip;y>23&&m[-9,9
              ]=d;puts(m)}}[1]#pY.E.@*'')

                                            8
self-descriptive FizzBuzz の実装
 1. ソースコード自身を文字列として得る
                                1. 自己複製

 2. 自分自身を次の数字の形に整形する
                        2. フォント埋め込み

 3. 以上を「実行可能なアスキーアート」として書く
                  3. 実行可能なアスキーアート



                                      9
1. 自己複製
• Quine 、自己出力プログラム、Print Me! とも

• ふつうの自己複製プログラム
       eval s=“
         s = ‘eval s=‘ + s.inspect;
         puts(s)
       “

     ※改行は分かりやすさのために入れています
     ※inspect: 文字列の前後に “ “ をつけるメソッド

• self-descriptive FizzBuzz でも同じ構造
                                      10
2. フォント圧縮
• 元データ (横 3 × 縦 5 × 約 15 文字 = 210 バイト)
    ### #       ### ### # # ###         ### ### ### ###         ###   ##
    # # ##        #   # # # #           #   # # # # # #         #     # # # # ## #
    # # #       ### ### ### ###         ###   # ### ###         ###   ## # # #
    # # #       #     #   #   #         # # # # #     #         #     # # # # # #
    ### ###     ### ###   # ###         ### # ### ###           #     ##   ## ## #

• # を 1、空白を 0 にして二進数に
    111   010   111   111   101   111   111   111   111   111   111   110   000   00   0
    101   110   001   001   101   100   100   101   101   101   100   101   101   11   1
    101   010   111   111   111   111   111   001   111   111   111   110   101   01   0
    101   010   100   001   001   001   101   010   101   001   100   101   101   10   1
    111   111   111   111   001   111   111   010   111   111   100   110   011   11   1

• 10 進表示に (64 バイト)
 1516849080105099949603183465996815374383250973658966149057739167

• to_s(36) で36進数に (41 バイト)
           8hlduayacv7bl0a0h2m2d2ti20qewh0rrsjcmsgpr
                                                                                           11
3. 実行可能なアスキーアート
1. コード全体を %w(       と ).join     で囲む
  –   %w(...) は文字列の配列のリテラル
      %w(foo bar)      [“foo”, “bar”]
  –   .join は配列を文字列として連結するメソッド

      [“foo”, “bar”].join      “foobar”

2. eval する                        eval %w(
                                  pu
                                     ts
3. 自由に整形できる! puts “Hi”
                                        “H
                                           i”
                                  ).join##
                                                12
以上の技法に基づいた他作品




                13
Qlobe: self-descriptive 地球儀プログラム
   v=0000;eval$s=%q~d=%!^Lcf<LK8,                       _@7gj*LJ=c5nM)Tp1g0%Xv.,S[<>YoP
   4ZojjV)O>qIH1/n[|2yE[>:ieC           "%.#% :::##"         97N-A&Kj_K_><wS5rtWk@*a+Y5
   yH?b[F^e7C/56j|pmRe+:)B       "##%        ::##########"       O98(Zh)'Iof*nm.,$C5Nyt=
   PPu01Avw^<IiQ=5$'D-y?      "##:           ###############"       g6`YT+qLw9k^ch|K'),tc
   6ygIL8xI#LNz3v}T=4W     "#               #.   .####:#######"       lL27FZ0ij)7TQCI)P7u
   }RT5-iJbbG5P-DHB<.    "                 ##### # :############"       R,YvZ_rnv6ky-G+4U'
   $*are@b4U351Q-ug5    "                 #######################"       00x8RR%`Om7VDp4M5
   PFixrPvl&<p[]1IJ    "                 ############:#### %#####"        EGgDt8Lm#;bc4zS^
   y]0`_PstfUxOC(q    "                 .#############:##%     .## ."      /,}.YOIFj(k&q_V
   zcaAi?]^lCVYp!; " %%                 .################.       #.     " ;s="v=%04o;ev"%
   (;v=(v-($*+[45, ":####:               :##############%          :    " ])[n=0].to_i;)%
   360)+"al$s=%q#{ "%######.                   #########                " ;;"%c"%126+$s<<
   126}";d.gsub!(/ "##########.                #######%                 " |¥s|".*"/,"");;
   require"zlib"|| "###########                :######.                 " ;d=d.unpack"C*"
   d.map{|c|n=(n|| ":#########:                .######: .               " )*90+(c-2)%91};
   e=["%x"%n].pack    " :#######%              :###### #:             "    &&"H*";e=Zlib::
   Inflate.inflate(    " ######%               .####% ::             "    &&e).unpack("b*"
   )[0];22.times{|y|    " ####%                 %###                "    ;w=(Math.sqrt(1-(
   (y*2.0-21)/22)**(;    " .###:                .#%                "    ;2))*23).floor;(w*
   2-1).times{|x|u=(e+     " %##                                "     )[y*z=360,z]*2;u=u[
   90*x/w+v+90,90/w];s[(      " #.                           "      ;y*80)+120-w+x]=(""<<
   32<<".:%#")[4*u.count((       " .                      "       ;"0"))/u.size]}};;puts¥
   s+";_ The Qlobe#{" "*18+ (           "# :#######"         ;"Copyright(C).Yusuke End¥
   oh, 2010")}";exit~;_ The Qlobe                       Copyright(C).Yusuke Endoh, 2010




                                                                                             14
Qlobe の実装
1. 自己複製する

2. 地球儀をレンダリングして出力する
  – 世界地図が zlib 圧縮で埋め込まれてます


3. 邪魔な地球儀はショートカット演算子などで回避

  “zlib” || “地球部分"     “zlib”
   “地球部分” && “H*”      “H*”
                                 15
山手Quine
 t="+,m-n./mAm0o1p23a4q56r7sBt89u-t-1:v;A<w4x=y1z>[?]A^@CD_    z=27;eval$s=%w!c,s=["H+{K}8k->dXNpv-cD~@?(zhAi~>JOv<-;A(]oH+MFKs*+KOB825i$%QX9~P=HC{iIlj*Sh#
 CD_EsF`GHmIJbKa*l";eval$s=%w{F=%q{ceY8#<DvO1=x&t9CSOqMYkzH    v=3U62LhUXhtnCx^{F=nuTtGG}@85_(xVvIWQ|Vllp[Gt22x&`^K3*ui;IW@O9-(`Z6V_T.E]%WHXYGa{O9A#msMgV{5
 U.kCpz+Vo8hB.1AF&tq21+$/IrMY]U.aDd!-1y!4MMGQm6m?bYh($QMYpX    R3XS/dxI8zM)XrbFom,$Msj8>=ca#i.yOqM-gtf2xH T#2VYW9Koq.)IjS:&n3f6$Q/@4-8m_[(HxaP>n*b]Ih/3`3T
 s4g,x1UlbNKH?>NzbisMn?sT@m3,F.Abb`xW!r%'%Ybee>xkUfjf[(*^Nd    uG-C~3Bn)d.PSdX8          uvtft?;j%bsM^v&h NcaFzv7)uyD=lkc+eYn5&dN/%.|o@pD|BPi+a`rJCgg>?AE;
 Xo_"@hQh%Fx*q[iB7EM"suSG8GVOIzceg/O=4CL,d[-k]twgVP`&wcfaT`    W~){4l9}","_m?PM(N5L <',.ht}f8B|*o8|Qg?:v '(@LY'1^KvIm8twKZHvU@:&FS)r[N1?t9k26*=tiLQw<Tq$l
 2M)j8sFY?(HKzOrVCHO_694[Uq8g @i/i;tMBG#;-;B]rV[])`3'<os^.     ]V1@Z3hnQ:cQ'b)>])-p }r'U[8hN       7`j6SW r-ZW m2 3n<ZaJ %C%g          @@+DABEERjKj5Yt~&>xL
 OV(SA<=ok%m[iV#qt[&dJ7SIdB;/ VUnVIrH;hEJ*QWD"E+5)gfrmD"#E     ~8BN`L#u?tE+CH$wM%*J px[D;A t%se'c waI. R; FIn( VUVq{0 6c Y]'1EV sqNd_V1yp8"].map{|
 XlNVv1j)^^                                       bCi_gw+s-V   s|n=0;s.unpack("C*") .map{| c|n=n* 91+(       c-1)%9 2};n}; e= "z=#{z =($*[i=0]?(z+1):z-
 J<?fWdtbnxRgJm4J.yHO_ay2e%rc Tj]ALVU'`V=]]W;x&9MP&g5zAVHR     1)%29};eval$s=%w"<<3 3<<$s[ 0,903] *3;1 4. time s{|y|b =" ";n=f= proc{|w|b<<e[i,w];
 ?B,SZA+!_[0f!TUCv$Hin?-G7hAL BW6w1x+F#%@FZ<7!9;vNxsj6HW_O     i+=w};t=s;f[4];z.dow nto(0){|       a|a<1& &6.t imes          {|x|      y>1&&y<12&&c[n*60+y*
 Ao)H5cv`Ves-BQ"Z                           =K$_[o]Can(;1cJp   6-x-67]>0?(b<<32<<32):f[2]}while(0<n=(t/=38)%38)};f[4];y>12& &b[-28,28]=""<<33<<"*''#..(c).
 HV<:4x2,AnZgqvsy >VWDZdF-+^ 46Z^Z@<>1< cJ3E4GYSqGg7$ocX       Yusuke.Endoh.2010";puts(b)}#c,s=["H+{K}8k->dXNpv-cD~@?      (zhAi~>JOv<-;A(]oH+MFKs*+KOB825i
 88=*`RVO*WskDY-# uj$t3$XP#U IH]regXHa_ >sta`lbL+=J3sL3e       $%QX9~P=HC{iIlj*Sh#v=3U62LhUXhtnCx^{F=nuTtGG}@85_(xVvIWQ|Vllp[Gt22x&`^K3*ui;IW@O9-(`Z6V_T.E]
 BYxm/a0]lV1?M4WA                           u7jCGk`UBzB#*gOJ   %WHXYGa{O9A#msMgV{5R3XS/dxI8zM)XrbFom,$Msj8>=ca#i.yOqM-gtf2xHT#2!*''#..(c).Yusuke.Endoh.2010
 wHu#gQst^XB0VXjT imG<qb[s!* S#":,frD+N wn=nI<u;#dw*Y?"8
 B#G[%YT$mvLd<gUd lN^6#bZX$S a#owd125V! 4d+zL5)I;JD-ToJ"
 uN?h9Braq+dG4Nr[                           ynH,hS?nk4JD^/.q



                                                               • 実行すると隣の駅名になる
 KS&kW@(62e]xb0j2(;4X[ROR2W      Ifjf^3vhJ5jb5"sJ(4b6Ek1?Vx
 %s$^.yD.SY$':h[zd$D7o$n: Zp F= 2bHENRzBQhsd_7Im*HZG3xcx
 t#KdN4D3tEG%#F[1pbo_6C y;kI "Z`: ]^-/]HnWCrJ^=JBA9%gyIr
 %Xe,D'&Lmb:S<o_(b4VJ ji*bc# G'#ig: AQR[vp>>Jn;Mf$KRBf&7
 [%X34447R.0v"Uz/4F "6Q+0>+1 N3OLCeMn ;8TQ>BHCW1";KrW,%P
 `C?@?)fz>c3B;r     8Q"QCjmU"3 SXd1Jt1qI;     "G7HLO$I*6=fCC



                                                               • 29 駅で元に戻る
 o!G6CSm1a]    S(S#d#sa#2lXP& 4$L"^ir8_BEmkS      vA!f@p!$A6
 pE@#u%5QJda>[dT>cc4bYcAY)6uF 9%1C4f?GWDcZR`n,%>JrTqK$eHG2
 W)B__.[JP+@2qlsWxug,O60@Nkj6VU#Gqp[fC%XOc`:C!-hbr3C0Dz2aLL
 RI%*4&Lto'OJxHohC=*H#sc][4ZwId0O,R]s<]D#ykgKY7Oc1`heSG/Xxj
 LA2aiV!<Q;8G/!8>GlX^T4P-/.oIyvR>kPyJ;lXD1r8n5gHPeuA4%j8*0>
 Iu^>CRxHz3HYX*#n,t_EjxBRbgFH kj:PmmNq3MA10LXwbAW&S^/0_x,H
 4d5"_9>K!n6*b(ij`:HQRKf]EJoM NwY>5Si'd#'5BuS8[sF`_[bf9Z<W
 vdK3HiV+1L.jL*%;&g.G#?S5:Xh$ /gWw#1U-lHTo"?_dxYHC&UGLa)yn
 %zdU1KPkrE                                       wXsKbTBBix
 xh=#es7os:-9<`3Olf(!YN!hK?1a,2UMJ^`IC)oc8Z/TipLWy(%p0qUZoO
 ;W#bB%8=9CZvoU$eG;kXt[hewZnV!(B(u-[L3)l,6C%3.?u?znQyMgw31s
 [s4Ne+XNPNcpmuaJ<]                       Hd:/;va-yp4)mU.&Vr
 Z@*N3mTZX)0]%^]0d6 a'@njg`2DJ;stf^WTr 3y%gWte5;+Q>ZbENlv
 rK!4M=y6IQ27&IJm>n w57+;)s=Foy<4pdw5i lSDhJRyao%_Wx+[lx6
 D8Goea3uRPpunFulWq 0*3GoGaJyAHF$#bJca 5&Z0K'r[o,K*"/^jv6
 m08,PTZy$g?eX[aN4j J]AkXcV72;!};f=0;F .unpack("C*").map{
 |c|f=f*89+((c-2)%9                       0-1)};require'zlib
 ';t=t.split*"";$*[0]?(t[/([* -K]+.)([*-K]+.)$/];t=$2+$`+s
 =$1):(s=t[/.+?[L-z]/];t=$'+s );f=Zlib::Inflate.inflate(Ma
 rshal.dump(f)[7..-1] );S=%{ t="#      {t}";eval$s=%w{#$s}*
 "";%|}+F*9;P=proc{pu ts(S.s lice!(0, 58));P};P[][][][s.
 upcase.unpack("C*" ).map{|c |c-=c>92?4 3:42;;P[][][20.t
 imes{|n|puts(("% 029b"%("¥0 "+f[60*c+3*n ,3]).unpack("N
 ")[0]).gsub(     /./){$&<"1"? (S.slice!(0,2) ):(32.chr*2)
 })}]}][];puts(*["+"+"-"*      25,"|,##,(c),Yusuke,Endoh,20
 09".split(",").join(32.chr)].map{|l|S.slice!(0,32)+l})}*""
 ;%|ceY8#<DvO1=x&t9CSOqMYkzHU.kCpz+Vo8hB.1AF&tq21+$/IrMY]U.
 aDd!-1y!4MMGQm6m?bYh($QMYpXs4g,x1UlbNKH?>NzbisMn?sT@m3,F.A
 bb`xW!r%'%Ybee>xkUfjf[(*^NdXo_"@+-------------------------
 hQh%Fx*q[iB7EM"suSG8GVOIzceg/O=4| ## (c) Yusuke Endoh 2009


                                                                                                                                                              16
自己相似 Quine
  eval$s=%w'k=0013;f=proc{|x,y,s|x*x+y*y*4<36864&&(u,v=x.ro
  eval$s=%w'k=0026;f=proc{|x,y,s|x*x+y*y*4<36864&&(u,v=x.ro
  eval$s=%w'k=0054;f=proc{|x,y,s|x*x+y*y*4<36864&&(u,v=x.ro
  eval$s=%w'k=0067;f=proc{|x,y,s|x*x+y*y*4<36864&&(u,v=x.ro
             eval$s=%w'k=0136;f=proc{|x,y,s|x*x+y*
                      eval$s=%w'k=0000;f=
  und,y.round;x.abs>21+s||y.abs>4+s||(x*x+(y*2+6)**2<4?f[x*
          y*4<36864&&(u,v=x.round,y.round;x.abs>21+
                  proc{|x,y,s|x*x+y*y*4<36864
  96,y*96+288,s*192]:u*u<441&&v*v<25&&"36effv0qbzox5c3npa19
        s||y.abs>4+s||(x*x+(y*2+6)**2<4?f[x*96,y*96+2
                &&(u,v=x.round,y.round;x.abs>21
  1hhgzrio5b3640nv9g9jzvnm8a67su".to_i(36)[u-v*41+143]>0))}
       88,s*192]:u*u<441&&v*v<25&&"36effv0qbzox5c3npa1
              +s||y.abs>4+s||(x*x+(y*2+6)**2<4?f[
  ;k=(k+($*[0]||0).to_i)%99;t=("eval$s=%%w%ck=%04o;"%[39,k]
     91hhgzrio5b3640nv9g9jzvnm8a67su".to_i(36)[u-v*41+14
           x*96,y*96+288,s*192]:u*u<441&&v*v<25&&"
                           ;k=(k+($*
  )<<($s[7,530]<<35<<35)*9;s=8/96**(1-k.to_f/98);o=(-11..11
    3]>0))};k=(k+($*[0]||0).to_i)%99;t=("eval$s=%%w%ck=%0
          36effv0qbzox5c3npa191hhgzrio5b3640nv9g9jz
                       [0]||0).to_i)%99;
  ).map{|j|(-28..28).map{|i|f[i*s,j*s-36*(8-s)/95,s/4]??a:3
   4o;"%[39,k])<<($s[7,530]<<35<<35)*9;s=8/96**(1-k.to_f/9
         vnm8a67su".to_i(36)[u-v*41+143]>0))};k=(k+(
                     t=("eval$s=%%w%ck=%04
  2.chr}*""}*10.chr;o.sub!(/aaaa((#{"Quine";(s=92.chr)+?s}+
   8);o=(-11..11).map{|j|(-28..28).map{|i|f[i*s,j*s-36*(8-
        $*[0]||0).to_i)%99;t=("eval$s=%%w%ck=%04o;"%[
                   o;"%[39,k])<<($s[7,530]<<
                           2.chr}*""
  a{1,3})*#{s+?s}*)#{s+?z}/){39.chr+%(*"")+$1.tr(?a,?;)};o.
  s)/95,s/4]??a:32.chr}*""}*10.chr;o.sub!(/aaaa((#{"Quine";
       39,k])<<($s[7,530]<<35<<35)*9;s=8/96**(1-k.to_f
                  35<<35)*9;s=8/96**(1-k.to_f
                         }*10.chr;o.su
  gsub!(/a/){t.slice!(0,1)};puts(*o)##f=proc{|x,y,s|x*x+y*y
  (s=92.chr)+?s}+a{1,3})*#{s+?s}*)#{s+?z}/){39.chr+%(*"")+$
       /98);o=(-11..11).map{|j|(-28..28).map{|i|f[i*s,
                  /98);o=(-11..11).map{|j|(-2
                        b!(/aaaa((#{"Qu
  gsub!(/a/){
  *4<36864&
  1.tr(?a,?;)};o.gsub!(/a/){t.slice!(0,1)};puts(*o)##f=proc
       j*s-36*(8-s)/95,s/4] t.sli ??a:32.chr}*""}*10.c
                 8..28).map{|i|f[i*s,j*s-36*(8
                       ine";(s=92.chr)+?
                              &(u                   ,v=x.roun
  ce!(0,1)};p
  d,y.round ;x.abs>2 s}+a{1,1 + 32.chr}*""}*
  {|x,y,s|x*x+y*y*4<36864&&(u,v=3})*#{s
       hr;o.sub!(/aaaa((#{" uts (*o";(s=92.chr)+?s}+a{1
                 -s)/95,s/4]?Quine x.round,y.round;x.abs>21+
                              ?a:                   s||y.abs>
  )
  4+s||(x*x +( 10.chr;o.sub!(/aaaa((#{"Quine
  s||y.abs>4+s||(x*x+(y*2+6)**2<4?f[x*96,y*96+288,s*192]:u*
       ,3})*#{s+?s}*)#{s+?z pro }/){39.chr+%(*"")+$1
          ##f=     y*2 +?s}*)#{s+?z}/){3            +6)**2<4?
  c
  f[x*96,y* 96 +y,s| ,sx*x+ 2]: u*u<441 &&v* v< 25&&"36ef
  u<441&&v*v<25&&"36effv0qbzox5c3npa191hhgzrio5b3640nv9g9jz
       .tr(?a,?;)};o.gsub!(/a/){t.slice!(0,1)};puts(*o
          {|x,    ";(s=92.chr)+?s}+a{1,3})*#{
                   288 9.chr+%(*"")+$1
                           *19 y*y* 4<36864&&(u      ,v=x.rou
  n
  fv0qbzox5 c3 npa19 1hd;x. rio 5b3 640 nv9g9jz vnm8a67su
  vnm8a67su".to_i(36)[u-v*41+143]>0))};k=(k+($*[0]||0).to_i
       )##f=proc{|x,y,s|x*x+y*y*4<36864&&(u,v=x.round,
          d,y. rouns+?s}*)#{s+?z}/){39.chr+%
                          .tr(?a,?;)}21+s||y.abs
                           hgz abs>                  >4+s||(x
  *)%99;t=("eval$s=%%w%ck=%04o;"%[39,k])<<($s[7,530]<<35<<
  ".to_i(36 )[ +6)* 41*2<4 ;o. 0)) };k *96+28 8,s*19 2
     x+ y.round;x.abs>21+s||y.abs>4+s||(x*x+(y*2+6)**
          (y*2    u-v*
                    (*"")+$1.tr(?a,?;)};o.g=(k
                           +14 ?f[x *96,y
                               3]>                  +($*[0]||
  ]35)*9;s=8/96**(1-k.to_f/98);o=(-11..11).map{|j|(-28..28p
  0).to_i)% 99;t=(" ev al$s=% %w% ck= %04 fv0qbz 9,k])<<($
     :u 2<4?f[x*96,y*96+288,s*192]:u*u<441&&v*v<25&
          *u<4 41&&sub!(/a/){t.slice!(0, o;"%[3 ox5c3n
                         v*v< 25&& "36ef
  a ).map{|i|f[i*s,j*s-36*(8-s)/95,s/4]??a:32.chr}*""}*10
  s[7,530]<
       191hhgz rio5
          &"36effv0qbzox5c3npa191hhgzrio5b3640nv9g9
                        1)};puts(*o)##f
                         b364 0nv9 g9jzv      nm8a <35<<35)*
                                                    67su".to_
  g
  i .chr;o.sub!(/aaaa((#{"Quine";(s=92.chr)+?s}+a{1,3})
  9;s=8/96**(1-k.to_f/98);o=(-11..11).map{|j|(-28..28).map{
        (36)[u -v*4
           jzvnm8a67su".to_i(36)[u-v*41+143]>0))}; ($*[
            sub!(/a/){t.s1+14lice!(0,1)};p
                              =pr
                               3]>0 ))};k     =(k+
                                                uts(*o)##f=pr
  o
  0
  |i|f[i*s,j*s-36*(8-s)/95,s/4]??a:32.chr}*""}*10.chr;o.sub
      *#{s+?s}*)#{s+?z}/){39.chr+%(*"")+$1.tr(?a,?;)};o
        ]||0). to_i
            c{|x,y,s|x*x+)%99y*y*4<36864&&
              k=(k+($*[0]||0).to_i)%99;t=("eval$s %w%c
                               ;t=( "eval     $s=%
                                                (u,v=x.round,
  y
  k=%04o;"%.round;x.abs>
  !(/aaaa((#{"Quine";(s=92.chr)+?s}+a{1,3})*#{s+?s}*)#{s+?z
        .gsub!(/a/){t.slice!(0,1)};puts(*o)##f=proc{|
              [39 ,k])<<($s[721+s||y.abs>4
                =%%w%ck=%04o;"%[39,k])<<($s[7,5 +s||(x*x+(y*2
                               ,530 ]<<35     <<35   )*9;s=8/
  +
  }/){39.chr+%(*"")+$1.tr(?a,?;)};o.gsub!(/a/){t.slice!(0,1
         x,y,s|x*x+y*y*4<36864&&(u,v=x.round,y.round
            6)**2<4?f[x*9
                  30]<<35<<35)*9;s=8/96**(1-k 192]:u*u<441&
                             6,y*96+288,s*
  oc{|x,y,s|x*x+y*y* .to_f/98);o=(-1'*""
  &
  96**(1-k.to_f/98);o=(-11..11).map{|j|(-28..28).map{|i'*""
  )};puts(*o)##f=proc{|x,y,s|x*x+y*y*4<36864&&(u,v=x.ro'*""
            v*v<25&&"36ef
             ;x.abs>21+s||y.abs>4+s||(x*x+(y*2'*""
                            4<36864&&(u,v=x.r'*""
                             fv0qbzox5c3np      a191hhgz'*""
                                                          ;;;
                                                                17
15quzzle
 Quine でパネル移動後の盤面が出てくる
           eval$s=%w[b=0 x40e1359a76cb d8f2;i=(m=0.. 15).find{|i|1
           >b&m=15<<4*i} ;t=m|n=m<<4*o =("AdABrBlBAu A"=~/(.)#{ARG
           V*''}¥1/||04| |0)-4;(n<1||n >1<<64||[255< <12]&[t>>040|
           |___________2 |__________15 |___________8 |__________13

           |0,t>>16,t]!= [])?t=0:i+=o; ;s="eval$s=%% w[b=0x%016x"%
           (b^=t.&b|m&b> >o*4)+$s.gsub (/(¥|_+¥d+)+/ ,'')[/;.*/]+"
           ]*''||0"<<92| |1;z=s=s.scan (/.{13}/);3.t imes{|j|s[(i|
           |__________11 |__________12 |___________6 |___________7

           |0)/4*8+i+j*4 ,0]=m=(z=32.c hr)*13};c=b;4 .times{puts((
           0..3.times{pu ts((s.slice!( 0,4)*z).rstri p)}).map{j=c%
           16;c/=16;;(0| |0)<(j)?"|"+j .to_s.rjust(1 2,"_"):m}*(z|
           |__________10 |___________9 |___________5 |___________3

           |0),z)};b==0x fedcba9876543              21&&("%b"%"1t
           v7c1th0wylel7 3ba35knw3t".t              o_i(36)).tr("
           01",".#").sca n(/.{25}/){pu              ts$&}]*''||0¥
           |___________1 |__________14              |___________4


                                                                     18
関連研究
• International Obfuscated C Code Contest (IOCCC)
     – みにくい C コードを書くコンテスト
   円周率計算プログラム                                        電卓プログラム             (hou [2011])
                    (westley [1988])    #include <stdio.h>
                                        #include <math.h>
#define _ -F<00||--F-OO--;              (略)
int F=00,OO=00;main(){F_OO();
printf("%1.3f¥n",4.*-F/OO/OO);}F_OO()   int main(int argc,char** argv){
{                                         if(argc<2){
            _-_-_-_                         puts(
       _-_-_-_-_-_-_-_-_                      usage: calculator 11/26+222/31
    _-_-_-_-_-_-_-_-_-_-_-_                   +~~~~~~~~~~~~~~~~~~~~~~~~calculator-¥
  _-_-_-_-_-_-_-_-_-_-_-_-_-_                 !                          7.584,367 )
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_                +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_                ! clear ! 0 ||l -x l tan I (/) |
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_               +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_               ! 1 | 2 | 3 ||l 1/x l cos I (*) |
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_               +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_                ! 4 | 5 | 6 ||l exp l sqrt I (+) |
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_                +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
  _-_-_-_-_-_-_-_-_-_-_-_-_-_                 ! 7 | 8 | 9 ||l sin l log I (-) |
    _-_-_-_-_-_-_-_-_-_-_-_                   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(0
        _-_-_-_-_-_-_-_                     );
            _-_-_-_                       }
}                                         return 0;
                                        }                                         19
超絶技巧プログラミングの実践


テーマ 1: self-descriptive な Ruby プログラム



テーマ 2: 文字を制限した Ruby プログラム




                                       20
使える文字を制限して Ruby を書く
• 今日のテーマ: 小文字アルファベット(と空白)だけ
• 実装方針
  – 実行したいコードの文字列を構築し、eval する

           eval “code”

• 説明の順序
 1. アルファベット(大文字含む)+数字だけで書く   (Hamaji [2008])

 2. 大文字を排除する
 3. 数字を排除する



                                       21
コード文字列を構築する
• 問題: 文字列リテラルは使えない
                           クォート使用不可
              “code”

• 解決: 文字列を返す組み込み関数を使う
 –例
        String nil        “”

 – nilを文字列に型変換する:空文字列が得られる
 – 空文字列に ASCII code で文字を連結していく

      “”.concat(65)       “A”
      “A”.concat(66)      “AB”
                                  22
ピリオドなしで concat を呼び出す
                            ピリオド・カッコ
• 問題: メソッドが呼び出せない
                             使用不可
            “”.concat(65)

• 解決: String のメソッドからはピリオドなしで呼べる
  – Ruby ではカッコは常に省略可能
   class String       空文字列からコードを
     def generate    構築するメソッドを定義する
       concat 65
       concat 66
                       新たな課題:
     end
                     この構築メソッド自身を
   end
                      どう呼び出すか?
   “”.generate
                                   23
コード構築メソッドを起動する
• Ruby の for 文
      for 変数 in コレクション do ... end
                       構文糖
      コレクション.each do |変数| ... end

∴ コード構築メソッドを each という名前にすれば
  ピリオドなしで呼び出せる

    “”.each   ≒   for elem in “” do end



                                          24
第一段階: アルファベットと数字で Ruby
例: コード文字列 “p 1” を構築・ eval するコード
 class String
   def each        文字列を構成する様子
     concat 112    “”
     concat 32          concat 112
     concat 49
     eval self      “p”
                           concat 32
     exit
   end                  “p ”
                               concat 49
 end
 for i in
                           “p 1” eval
   String nil do
 end
                                           25
class String
大文字を排除する                    def each
                              ...
• String の ”S” が 2 箇所       end
                          end
• class String の箇所        for i in
  – String クラスには定義できない     String nil do
                          end
  – トップレベルは Object クラス
      トップレベルに定義すればよい
                          public
                          def each
• String nil の箇所            clear
  – 文字列を返す別のメソッドにする         ...
  – String#clear で空文字列に   end
                          for i in
                           String nil do
                            inspect do
                          end          26
第二段階: 小文字 alphabetと数字で Ruby
例: “1” を出力するコード
  class String      public
    def each        def each
      concat 112      clear
      concat 32       concat 112
      concat 49       concat 32
      eval self       concat 49
      exit            eval self
    end               exit
  end               end
  for i in          for i in
    String nil do     inspect do
  end               end
                                   27
数字を排除する(1)
• 欲しい数字の長さの文字列を作り size を呼ぶ
 – 例: 8 を生成するコード

   clear           #   “”
   concat   size   #   “¥0”
   concat   self   #   “¥0¥0”
   concat   self   #   “¥0¥0¥0¥0”
   concat   self   #   “¥0¥0¥0¥0¥0¥0¥0¥0”
   size            #   23 = 8 が得られる


• 今まで構築してきたコードが消えてしまう!


                                            28
数字を排除する(2)
• 例外処理の構文                           現在の self
                                          “...”
  begin A ensure B end
 – Java の try { A } finally { B }
                                        concat begin
   みたいなもの                                 dup
• 式全体が A の評価結果を返す                       ensure
                                          concat begin
 – A を評価し                                   65 を作る
                                          ensure
 – B を評価し                                   clear
                                          end
 – B の評価結果を捨てて                          end
   A の評価結果を返す構文
• 文字列の先頭に 1 文字追加
  するイディオムが作れる                            “A...”
                                    新しい self
                                                         29
loop         do      break       public      end
                                                    catch        inspect       do      def      each
                                                    loop         do       break      clear       end
                                                    concat       begin      dup     ensure     clear
                                                    concat       concat    concat     concat    size
                                                    loop     do break    concat   concat size    end
                                                    loop     do break    concat   concat size    end




小文字アルファベットだけで Ruby を書く
                                                    loop      do     break    concat     size    end
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    concat   concat concat concat concat concat size
                                                    loop      do     break    concat     size    end
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    loop     do break    concat   concat size    end
                                                    concat       concat    concat     concat    size
                                                    concat          concat        concat        size
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    loop     do break    concat   concat size    end
                                                    concat          concat        concat        size
                                                    loop     do break    concat   concat size    end
                                                    concat          concat        concat        size



 loop       do       break        public      end
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    loop     do break    concat   concat size    end
                                                    loop     do break    concat   concat size    end
                                                    concat       concat    concat     concat    size
                                                    loop     do break    concat   concat size    end



 catch      inspect         do      def      each
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    loop     do break    concat   concat size    end
                                                    concat          concat        concat        size
                                                    loop     do break    concat   concat size    end
                                                    loop     do break    concat   concat size    end



 loop       do        break       clear       end
                                                    loop     do break    concat   concat size    end
                                                    loop      do     break    concat     size    end
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    loop     do break    concat   concat size    end
                                                    loop     do break    concat   concat size    end



 concat     begin       dup      ensure     clear
                                                    concat          concat        concat        size
                                                    loop     do break    concat   concat size    end
                                                    loop     do break    concat   concat size    end
                                                    loop      do     break    concat     size    end
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear



 concat     concat     concat      concat    size
                                                    concat   concat concat concat concat concat size
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    concat          concat        concat        size
                                                    loop     do break    concat   concat size    end
                                                    concat          concat        concat        size



 loop   do break     concat    concat size    end
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    loop     do break    concat   concat size    end
                                                    concat          concat        concat        size
                                                    loop     do break    concat   concat size    end
                                                    loop     do break    concat   concat size    end



 loop   do break     concat    concat size    end
                                                    loop     do break    concat   concat size    end
                                                    loop      do     break    concat     size    end
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    loop     do break    concat   concat size    end
                                                    concat          concat        concat        size



 loop    do     break      concat     size    end
                                                    loop     do break    concat   concat size    end
                                                    concat          concat        concat        size
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    loop     do break    concat   concat size    end
                                                    concat          concat        concat        size



 concat begin     size ensure clear      end end
                                                    loop     do break    concat   concat size    end
                                                    concat          concat        concat        size
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    loop     do break    concat   concat size    end
                                                    concat       concat    concat     concat    size



 concat     begin       dup      ensure     clear
                                                    concat          concat        concat        size
                                                    loop      do     break    concat     size    end
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    concat       concat    concat     concat    size
                                                    concat       concat    concat     concat    size



 concat concat concat concat concat concat size
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    concat       concat    concat     concat    size
                                                    loop     do break    concat   concat size    end
                                                    loop     do break    concat   concat size    end
                                                    loop      do     break    concat     size    end



 loop    do     break      concat     size    end
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    loop     do break    concat   concat size    end
                                                    loop     do break    concat   concat size    end
                                                    concat       concat    concat     concat    size
                                                    loop     do break    concat   concat size    end
                                                    loop      do     break    concat     size    end
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    loop     do break    concat   concat size    end
                                                    loop     do break    concat   concat size    end
                                                    concat          concat        concat        size
                                                    concat          concat        concat        size
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    loop     do break    concat   concat size    end
                                                    loop     do break    concat   concat size    end
                                                    concat          concat        concat        size
                                                    concat          concat        concat        size
                                                    loop      do     break    concat     size    end
                                                    concat    begin   size ensure clear     end end
                                                    concat       begin      dup     ensure     clear
                                                    loop     do break    concat   concat size    end
                                                    loop     do break    concat   concat size    end
                                                    concat    concat   concat concat    concat size
                                                    concat    begin   size ensure clear     end end
                                                    loop       do     break    eval     self     end
                                                    loop       do      exit     end      end     end
                                                    for         each       in       inspect       do


                                                                       30           copyright mmxii
                                                                                        yusuke end
                                                                                                  o
                                                                                                  h
関連研究: 他の文字制限の例
                             _=[*' '..?~]*'';$><<_[(___=_=~/@/
• 記号だけ   (kurimura [2008])   ).+_=~/¥(/]+_[(__=_=~/_/).+_=~/&/
                             ]+_[__+@@_=_=~/¥-/]+_[__+@@_]+_[(
                             @_=_=~/~/)-@@_=_=~/¥//]+", "+_[
                             @_.-_=~/'/]+_[@_-@@_]+_[@_.-_=~
                             /,/]+_[__.+_=~/¥-/]+_[__.+_=~/%/
                             ]+?!+$/



• 数字(+ require)だけ            require "1234567890"

                             316805813369061470447252554255354
                             816767578747985092956934801232229
                             450578663292118901228453190669621
                             8369564670777459615871118090530


                             require "_"
• アンダースコア(+ require)         ____ _ _____ ____ __ ____ ____
                             __ ___ ____ __ __ _ ______ _____

  だけ                         ___ _ _ ___ _____ ______ ____ _
                             _ ____ _ _ ____ _ ____ __ __ ___
                             _ ______ ___ ____ __ ______ ____
                             _ ____ ____ __ _ ____ _ _ ___
                             _____ _____ _ ______ ____ _
                             ______ _____




                                                           31
関連研究: 他言語での文字制限の例
• Perl: 記号だけ                                          (Takesako [2005])


      Quiz: これは何をするプログラムでしょう?                                                まとめ

                                                                        Let’s 予約語プログラミング♪
    #!/usr/bin/perl                                                       Perl 以外の言語でも実装できますか?
    sin cos and s qq qx xor s x x print uc chr lc                                      awk ?
    ord qq sleep times x xor int log cos xor eval                                      Haskell ?
                                                                                        Lisp ?
    and eval and print uc chr ord scalar reverse
                                                                                    

                                                                                       ML ?
    qq exit binmode xor qq write qw xor print uc                                       Perl → OK !
    chr ord scalar reverse qw tell my print                                            PHP ?
                                                                                       Python ?                             挑戦者求む!
                                                                                       Ruby ?
  正解 → 標準出力に “LLDN” という文字列を出力するプログラム

2005/08/27   Lightweight Language Day and Night                    4   2005/08/27       Lightweight Language Day and Night             18




• Javascript
             – 記号だけ                               (Hasegawa [?])

             – 顔文字だけ                              (Hasegawa [?])


                                                                                                                                      32
目次
• 背景: 近年のプログラミングの問題
• 提案: 超絶技巧プログラミング
 – 実践1: self-descriptive な Ruby プログラム
 – 実践2: 文字を制限された Ruby プログラム

• まとめ




                                        33
まとめ
• 超絶技巧プログラミングを紹介した
 – 実用性を無視して「美しい」プログラミング


• みなさんもいかがでしょうか
 – IOCCC開催中 
 – 9/15 まで




                          34

Mais conteúdo relacionado

Mais procurados

㉘HTML5+CSS3でアニメーション!
㉘HTML5+CSS3でアニメーション!㉘HTML5+CSS3でアニメーション!
㉘HTML5+CSS3でアニメーション!Nishida Kansuke
 
WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!
WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!
WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!文樹 高橋
 
One - Common Lispでもワンライナーしたい
One - Common LispでもワンライナーしたいOne - Common Lispでもワンライナーしたい
One - Common Lispでもワンライナーしたいt-sin
 
簡単!OpenGL ES 2.0フラグメントシェーダー
簡単!OpenGL ES 2.0フラグメントシェーダー簡単!OpenGL ES 2.0フラグメントシェーダー
簡単!OpenGL ES 2.0フラグメントシェーダーEiji Kamiya
 
IdrisでWebアプリを書く
IdrisでWebアプリを書くIdrisでWebアプリを書く
IdrisでWebアプリを書くHideyuki Tanaka
 
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013Ryo Sakamoto
 
シュッとふりかえる Ruby 2.0 以降
シュッとふりかえる Ruby 2.0 以降シュッとふりかえる Ruby 2.0 以降
シュッとふりかえる Ruby 2.0 以降Tomohiro Nishimura
 
Play frameworkをエヴァンジェる
Play frameworkをエヴァンジェるPlay frameworkをエヴァンジェる
Play frameworkをエヴァンジェるke-m kamekoopa
 
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01nagachika t
 
brainfuckを吐く自作言語bf-reusable
brainfuckを吐く自作言語bf-reusablebrainfuckを吐く自作言語bf-reusable
brainfuckを吐く自作言語bf-reusableroodni
 
Interactive Music II SuperCollider入門 5 時間構造をつくる
Interactive Music II SuperCollider入門 5  時間構造をつくるInteractive Music II SuperCollider入門 5  時間構造をつくる
Interactive Music II SuperCollider入門 5 時間構造をつくるAtsushi Tadokoro
 
「はじめよう、シェル芸」オープンキャンプin南島原2020/OpenCamp in Minami-shimabara online
「はじめよう、シェル芸」オープンキャンプin南島原2020/OpenCamp in Minami-shimabara online「はじめよう、シェル芸」オープンキャンプin南島原2020/OpenCamp in Minami-shimabara online
「はじめよう、シェル芸」オープンキャンプin南島原2020/OpenCamp in Minami-shimabara onlineHisatoshi Onishi
 
実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)AtCoder Inc.
 
Popcntによるハミング距離計算
Popcntによるハミング距離計算Popcntによるハミング距離計算
Popcntによるハミング距離計算Norishige Fukushima
 
Virtual rootkit
Virtual rootkitVirtual rootkit
Virtual rootkit黒 林檎
 
板ポリだけで めちゃカッコいい グラフィックスを出す!
板ポリだけで めちゃカッコいい グラフィックスを出す!板ポリだけで めちゃカッコいい グラフィックスを出す!
板ポリだけで めちゃカッコいい グラフィックスを出す!notargs
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングKohsuke Yuasa
 
Ruby初級者向けレッスン 56回 ─── ブロック
Ruby初級者向けレッスン 56回 ─── ブロックRuby初級者向けレッスン 56回 ─── ブロック
Ruby初級者向けレッスン 56回 ─── ブロックhigaki
 
20130216 シェル芸爆破デスマッチ勉強会
20130216 シェル芸爆破デスマッチ勉強会20130216 シェル芸爆破デスマッチ勉強会
20130216 シェル芸爆破デスマッチ勉強会Ryuichi Ueda
 

Mais procurados (20)

㉘HTML5+CSS3でアニメーション!
㉘HTML5+CSS3でアニメーション!㉘HTML5+CSS3でアニメーション!
㉘HTML5+CSS3でアニメーション!
 
WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!
WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!
WPD-Fes #3 2015年のサバイバル学習術 Web開発技術の税引後利益 を最大化しよう!
 
One - Common Lispでもワンライナーしたい
One - Common LispでもワンライナーしたいOne - Common Lispでもワンライナーしたい
One - Common Lispでもワンライナーしたい
 
簡単!OpenGL ES 2.0フラグメントシェーダー
簡単!OpenGL ES 2.0フラグメントシェーダー簡単!OpenGL ES 2.0フラグメントシェーダー
簡単!OpenGL ES 2.0フラグメントシェーダー
 
IdrisでWebアプリを書く
IdrisでWebアプリを書くIdrisでWebアプリを書く
IdrisでWebアプリを書く
 
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
 
シュッとふりかえる Ruby 2.0 以降
シュッとふりかえる Ruby 2.0 以降シュッとふりかえる Ruby 2.0 以降
シュッとふりかえる Ruby 2.0 以降
 
Play frameworkをエヴァンジェる
Play frameworkをエヴァンジェるPlay frameworkをエヴァンジェる
Play frameworkをエヴァンジェる
 
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
 
brainfuckを吐く自作言語bf-reusable
brainfuckを吐く自作言語bf-reusablebrainfuckを吐く自作言語bf-reusable
brainfuckを吐く自作言語bf-reusable
 
Interactive Music II SuperCollider入門 5 時間構造をつくる
Interactive Music II SuperCollider入門 5  時間構造をつくるInteractive Music II SuperCollider入門 5  時間構造をつくる
Interactive Music II SuperCollider入門 5 時間構造をつくる
 
「はじめよう、シェル芸」オープンキャンプin南島原2020/OpenCamp in Minami-shimabara online
「はじめよう、シェル芸」オープンキャンプin南島原2020/OpenCamp in Minami-shimabara online「はじめよう、シェル芸」オープンキャンプin南島原2020/OpenCamp in Minami-shimabara online
「はじめよう、シェル芸」オープンキャンプin南島原2020/OpenCamp in Minami-shimabara online
 
実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)
実践・最強最速のアルゴリズム勉強会 第四回講義資料(ワークスアプリケーションズ & AtCoder)
 
Popcntによるハミング距離計算
Popcntによるハミング距離計算Popcntによるハミング距離計算
Popcntによるハミング距離計算
 
Virtual rootkit
Virtual rootkitVirtual rootkit
Virtual rootkit
 
pecoを使おう
pecoを使おうpecoを使おう
pecoを使おう
 
板ポリだけで めちゃカッコいい グラフィックスを出す!
板ポリだけで めちゃカッコいい グラフィックスを出す!板ポリだけで めちゃカッコいい グラフィックスを出す!
板ポリだけで めちゃカッコいい グラフィックスを出す!
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
 
Ruby初級者向けレッスン 56回 ─── ブロック
Ruby初級者向けレッスン 56回 ─── ブロックRuby初級者向けレッスン 56回 ─── ブロック
Ruby初級者向けレッスン 56回 ─── ブロック
 
20130216 シェル芸爆破デスマッチ勉強会
20130216 シェル芸爆破デスマッチ勉強会20130216 シェル芸爆破デスマッチ勉強会
20130216 シェル芸爆破デスマッチ勉強会
 

Semelhante a Ruby を用いた超絶技巧プログラミング(夏のプログラミングシンポジウム 2012)

入門 超絶技巧プログラミング !
入門 超絶技巧プログラミング !入門 超絶技巧プログラミング !
入門 超絶技巧プログラミング !Nobutada Matsubara
 
⑰jQueryをおぼえよう!その3
⑰jQueryをおぼえよう!その3⑰jQueryをおぼえよう!その3
⑰jQueryをおぼえよう!その3Nishida Kansuke
 
㉗HTML5+jQueryでお絵かき
㉗HTML5+jQueryでお絵かき㉗HTML5+jQueryでお絵かき
㉗HTML5+jQueryでお絵かきNishida Kansuke
 
Reading Self-descriptive FizzBuzz
Reading Self-descriptive FizzBuzzReading Self-descriptive FizzBuzz
Reading Self-descriptive FizzBuzzHiroyuki Morita
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~Nobuhisa Koizumi
 
メンテできないコードをメンテする技術
メンテできないコードをメンテする技術メンテできないコードをメンテする技術
メンテできないコードをメンテする技術Tomoya Ishida
 
Tfpモデリングスペキュレーション
TfpモデリングスペキュレーションTfpモデリングスペキュレーション
TfpモデリングスペキュレーションEiichi Hayashi
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2Masao Kato
 
openFrameworks Workshop in Kanazawa v001
openFrameworks Workshop in Kanazawa v001openFrameworks Workshop in Kanazawa v001
openFrameworks Workshop in Kanazawa v001Teruaki Tsubokura
 
第2回 JavaScriptから始めるプログラミング2016
第2回 JavaScriptから始めるプログラミング2016第2回 JavaScriptから始めるプログラミング2016
第2回 JavaScriptから始めるプログラミング2016kyoto university
 
RでGISハンズオンセッション
RでGISハンズオンセッションRでGISハンズオンセッション
RでGISハンズオンセッションarctic_tern265
 
2012年10月27日 Hbstudy#38
2012年10月27日 Hbstudy#382012年10月27日 Hbstudy#38
2012年10月27日 Hbstudy#38Ryuichi Ueda
 
20150725 オープンキャンパス資料
20150725 オープンキャンパス資料20150725 オープンキャンパス資料
20150725 オープンキャンパス資料Takeo Kunishima
 
岡山県立大学オープンキャンパス資料
岡山県立大学オープンキャンパス資料岡山県立大学オープンキャンパス資料
岡山県立大学オープンキャンパス資料Takeo Kunishima
 
Mac Rubyではじめる!Macアプリ開発入門
Mac Rubyではじめる!Macアプリ開発入門Mac Rubyではじめる!Macアプリ開発入門
Mac Rubyではじめる!Macアプリ開発入門宏治 高尾
 
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和schoowebcampus
 
FRT Vol. 4 インサイド・クラウドプラットフォーム
FRT Vol. 4 インサイド・クラウドプラットフォームFRT Vol. 4 インサイド・クラウドプラットフォーム
FRT Vol. 4 インサイド・クラウドプラットフォームYasunari Goto (iChain. Inc.)
 
動的計画法の並列化
動的計画法の並列化動的計画法の並列化
動的計画法の並列化Proktmr
 

Semelhante a Ruby を用いた超絶技巧プログラミング(夏のプログラミングシンポジウム 2012) (20)

入門 超絶技巧プログラミング !
入門 超絶技巧プログラミング !入門 超絶技巧プログラミング !
入門 超絶技巧プログラミング !
 
⑰jQueryをおぼえよう!その3
⑰jQueryをおぼえよう!その3⑰jQueryをおぼえよう!その3
⑰jQueryをおぼえよう!その3
 
㉗HTML5+jQueryでお絵かき
㉗HTML5+jQueryでお絵かき㉗HTML5+jQueryでお絵かき
㉗HTML5+jQueryでお絵かき
 
Tokyo r33 beginner
Tokyo r33 beginnerTokyo r33 beginner
Tokyo r33 beginner
 
STC-OC2019_1st201906
STC-OC2019_1st201906STC-OC2019_1st201906
STC-OC2019_1st201906
 
Reading Self-descriptive FizzBuzz
Reading Self-descriptive FizzBuzzReading Self-descriptive FizzBuzz
Reading Self-descriptive FizzBuzz
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
 
メンテできないコードをメンテする技術
メンテできないコードをメンテする技術メンテできないコードをメンテする技術
メンテできないコードをメンテする技術
 
Tfpモデリングスペキュレーション
TfpモデリングスペキュレーションTfpモデリングスペキュレーション
Tfpモデリングスペキュレーション
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
 
openFrameworks Workshop in Kanazawa v001
openFrameworks Workshop in Kanazawa v001openFrameworks Workshop in Kanazawa v001
openFrameworks Workshop in Kanazawa v001
 
第2回 JavaScriptから始めるプログラミング2016
第2回 JavaScriptから始めるプログラミング2016第2回 JavaScriptから始めるプログラミング2016
第2回 JavaScriptから始めるプログラミング2016
 
RでGISハンズオンセッション
RでGISハンズオンセッションRでGISハンズオンセッション
RでGISハンズオンセッション
 
2012年10月27日 Hbstudy#38
2012年10月27日 Hbstudy#382012年10月27日 Hbstudy#38
2012年10月27日 Hbstudy#38
 
20150725 オープンキャンパス資料
20150725 オープンキャンパス資料20150725 オープンキャンパス資料
20150725 オープンキャンパス資料
 
岡山県立大学オープンキャンパス資料
岡山県立大学オープンキャンパス資料岡山県立大学オープンキャンパス資料
岡山県立大学オープンキャンパス資料
 
Mac Rubyではじめる!Macアプリ開発入門
Mac Rubyではじめる!Macアプリ開発入門Mac Rubyではじめる!Macアプリ開発入門
Mac Rubyではじめる!Macアプリ開発入門
 
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
 
FRT Vol. 4 インサイド・クラウドプラットフォーム
FRT Vol. 4 インサイド・クラウドプラットフォームFRT Vol. 4 インサイド・クラウドプラットフォーム
FRT Vol. 4 インサイド・クラウドプラットフォーム
 
動的計画法の並列化
動的計画法の並列化動的計画法の並列化
動的計画法の並列化
 

Mais de mametter

error_highlight: User-friendly Error Diagnostics
error_highlight: User-friendly Error Diagnosticserror_highlight: User-friendly Error Diagnostics
error_highlight: User-friendly Error Diagnosticsmametter
 
TRICK 2022 Results
TRICK 2022 ResultsTRICK 2022 Results
TRICK 2022 Resultsmametter
 
Enjoy Ruby Programming in IDE and TypeProf
Enjoy Ruby Programming in IDE and TypeProfEnjoy Ruby Programming in IDE and TypeProf
Enjoy Ruby Programming in IDE and TypeProfmametter
 
TypeProf for IDE: Enrich Development Experience without Annotations
TypeProf for IDE: Enrich Development Experience without AnnotationsTypeProf for IDE: Enrich Development Experience without Annotations
TypeProf for IDE: Enrich Development Experience without Annotationsmametter
 
Ruby 3の型解析に向けた計画
Ruby 3の型解析に向けた計画Ruby 3の型解析に向けた計画
Ruby 3の型解析に向けた計画mametter
 
emruby: ブラウザで動くRuby
emruby: ブラウザで動くRubyemruby: ブラウザで動くRuby
emruby: ブラウザで動くRubymametter
 
Type Profiler: Ambitious Type Inference for Ruby 3
Type Profiler: Ambitious Type Inference for Ruby 3Type Profiler: Ambitious Type Inference for Ruby 3
Type Profiler: Ambitious Type Inference for Ruby 3mametter
 
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析mametter
 
Ruby 3の型推論やってます
Ruby 3の型推論やってますRuby 3の型推論やってます
Ruby 3の型推論やってますmametter
 
マニアックなRuby 2.7新機能紹介
マニアックなRuby 2.7新機能紹介マニアックなRuby 2.7新機能紹介
マニアックなRuby 2.7新機能紹介mametter
 
A Static Type Analyzer of Untyped Ruby Code for Ruby 3
A Static Type Analyzer of Untyped Ruby Code for Ruby 3A Static Type Analyzer of Untyped Ruby Code for Ruby 3
A Static Type Analyzer of Untyped Ruby Code for Ruby 3mametter
 
A Plan towards Ruby 3 Types
A Plan towards Ruby 3 TypesA Plan towards Ruby 3 Types
A Plan towards Ruby 3 Typesmametter
 
Ruby 3 の型解析に向けた計画
Ruby 3 の型解析に向けた計画Ruby 3 の型解析に向けた計画
Ruby 3 の型解析に向けた計画mametter
 
A Type-level Ruby Interpreter for Testing and Understanding
A Type-level Ruby Interpreter for Testing and UnderstandingA Type-level Ruby Interpreter for Testing and Understanding
A Type-level Ruby Interpreter for Testing and Understandingmametter
 
本番環境で使える実行コード記録機能
本番環境で使える実行コード記録機能本番環境で使える実行コード記録機能
本番環境で使える実行コード記録機能mametter
 
Transcendental Programming in Ruby
Transcendental Programming in RubyTranscendental Programming in Ruby
Transcendental Programming in Rubymametter
 
Cookpad Hackarade #04: Create Your Own Interpreter
Cookpad Hackarade #04: Create Your Own InterpreterCookpad Hackarade #04: Create Your Own Interpreter
Cookpad Hackarade #04: Create Your Own Interpretermametter
 
Ruby 3のキーワード引数について考える
Ruby 3のキーワード引数について考えるRuby 3のキーワード引数について考える
Ruby 3のキーワード引数について考えるmametter
 
TRICK 2018 results
TRICK 2018 resultsTRICK 2018 results
TRICK 2018 resultsmametter
 
Type Profiler: An Analysis to guess type signatures
Type Profiler: An Analysis to guess type signaturesType Profiler: An Analysis to guess type signatures
Type Profiler: An Analysis to guess type signaturesmametter
 

Mais de mametter (20)

error_highlight: User-friendly Error Diagnostics
error_highlight: User-friendly Error Diagnosticserror_highlight: User-friendly Error Diagnostics
error_highlight: User-friendly Error Diagnostics
 
TRICK 2022 Results
TRICK 2022 ResultsTRICK 2022 Results
TRICK 2022 Results
 
Enjoy Ruby Programming in IDE and TypeProf
Enjoy Ruby Programming in IDE and TypeProfEnjoy Ruby Programming in IDE and TypeProf
Enjoy Ruby Programming in IDE and TypeProf
 
TypeProf for IDE: Enrich Development Experience without Annotations
TypeProf for IDE: Enrich Development Experience without AnnotationsTypeProf for IDE: Enrich Development Experience without Annotations
TypeProf for IDE: Enrich Development Experience without Annotations
 
Ruby 3の型解析に向けた計画
Ruby 3の型解析に向けた計画Ruby 3の型解析に向けた計画
Ruby 3の型解析に向けた計画
 
emruby: ブラウザで動くRuby
emruby: ブラウザで動くRubyemruby: ブラウザで動くRuby
emruby: ブラウザで動くRuby
 
Type Profiler: Ambitious Type Inference for Ruby 3
Type Profiler: Ambitious Type Inference for Ruby 3Type Profiler: Ambitious Type Inference for Ruby 3
Type Profiler: Ambitious Type Inference for Ruby 3
 
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
 
Ruby 3の型推論やってます
Ruby 3の型推論やってますRuby 3の型推論やってます
Ruby 3の型推論やってます
 
マニアックなRuby 2.7新機能紹介
マニアックなRuby 2.7新機能紹介マニアックなRuby 2.7新機能紹介
マニアックなRuby 2.7新機能紹介
 
A Static Type Analyzer of Untyped Ruby Code for Ruby 3
A Static Type Analyzer of Untyped Ruby Code for Ruby 3A Static Type Analyzer of Untyped Ruby Code for Ruby 3
A Static Type Analyzer of Untyped Ruby Code for Ruby 3
 
A Plan towards Ruby 3 Types
A Plan towards Ruby 3 TypesA Plan towards Ruby 3 Types
A Plan towards Ruby 3 Types
 
Ruby 3 の型解析に向けた計画
Ruby 3 の型解析に向けた計画Ruby 3 の型解析に向けた計画
Ruby 3 の型解析に向けた計画
 
A Type-level Ruby Interpreter for Testing and Understanding
A Type-level Ruby Interpreter for Testing and UnderstandingA Type-level Ruby Interpreter for Testing and Understanding
A Type-level Ruby Interpreter for Testing and Understanding
 
本番環境で使える実行コード記録機能
本番環境で使える実行コード記録機能本番環境で使える実行コード記録機能
本番環境で使える実行コード記録機能
 
Transcendental Programming in Ruby
Transcendental Programming in RubyTranscendental Programming in Ruby
Transcendental Programming in Ruby
 
Cookpad Hackarade #04: Create Your Own Interpreter
Cookpad Hackarade #04: Create Your Own InterpreterCookpad Hackarade #04: Create Your Own Interpreter
Cookpad Hackarade #04: Create Your Own Interpreter
 
Ruby 3のキーワード引数について考える
Ruby 3のキーワード引数について考えるRuby 3のキーワード引数について考える
Ruby 3のキーワード引数について考える
 
TRICK 2018 results
TRICK 2018 resultsTRICK 2018 results
TRICK 2018 results
 
Type Profiler: An Analysis to guess type signatures
Type Profiler: An Analysis to guess type signaturesType Profiler: An Analysis to guess type signatures
Type Profiler: An Analysis to guess type signatures
 

Ruby を用いた超絶技巧プログラミング(夏のプログラミングシンポジウム 2012)

  • 2. 宣伝: 翻訳本買ってください 抽象によるソフトウェア設計(Daniel Jackson 著) – 中島震 監訳 ・ 今井健男・酒井政裕・遠藤侑介・片岡欣夫 共訳 (オーム社) – 会場で買えます! Types and Programming Languages (通称 TAPL) – Benjamin C. Pierce 著 – 絶賛翻訳中! 2
  • 3. 目次 • 背景: 近年のプログラミングの問題 • 提案: 超絶技巧プログラミング • 実践 テーマ1: self-descriptive な Ruby プログラム テーマ2: 文字を制限された Ruby プログラム • まとめ 3
  • 4. 近年のプログラミングの問題 • 俗世の欲にまみれすぎ – 例: プログラミング言語 Ruby の宣伝文句 生産性が10倍! 10分でblogが 作れる! プログラミングが 楽しくなる! 実用性なんか無くてもプログラミングは楽しい! ※個人の感想です 4
  • 5. 提案: 超絶技巧プログラミング • 実用性を無視して美しいプログラムを書く行為 – 普通のプログラミング  puts “Hello, world!” – 超絶技巧プログラミング  alias|send¥ ;$stdin=GC | "%p?"%def# FALSE.gets();(8 | 64).chr+232424. to_s(25)+", "+%w|w ! | *"orlc". next<<012|| (c).Yusuke end;"oh, 2009" | "stegano-X."[0,4].reverse d,be="whydoes","crypto";:make. | %.mains..tr'eams',be.delete(d) • 由来: 超絶技巧練習曲 Transcendental Études (Liszt [1826]) – Transcendental: 「肉体・精神・魂のすべてを超越する」 http://ja.wikipedia.org/wiki/超絶技巧練習曲 5
  • 6. 超絶技巧プログラミングの実践 テーマ 1: self-descriptive な Ruby プログラム テーマ 2: 文字を制限した Ruby プログラム 6
  • 7. 例題: FizzBuzz • 数字を 1 から順に出力する、ただし – 3 で割り切れる場合は "Fizz" – 5 で割り切れる場合は "Buzz" – 両方で割り切れる場合は "FizzBuzz" を出力する • 普通の Ruby プログラミングで FizzBuzz n = 1 while true case when n % 15 == 0 then puts "FizzBuzz" when n % 3 == 0 then puts "Fizz" when n % 5 == 0 then puts "Buzz" else puts n end n += 1 end 7
  • 8. self-descriptive FizzBuzz eval(s=s= %w@proc{| n|z=32.ch r;k="[#{n +=1}]";u= ":>==;<==?"[m=n**4 %-15,m+13]||"#{$f= k}";d="Y.E.#{c=64. chr}*'')";$f||d<<z +k;t="eval(s=s=%w# {c+s=s[0, 334]}#$f# ";25.time s{|y|m=u. bytes.map {|v|t<<s; (0..[62-v ,2].min). map{|x|"i f0zgl11p0 zghuhku744d8hzeg41qtfx7xs7t wflr".to_i(36)[x+32+v*3-y/5 *44]<1?z*9:t.slice!(0,9)}<< z}.join.rstrip;y>23&&m[-9,9 ]=d;puts(m)}}[1]#pY.E.@*'') 8
  • 9. self-descriptive FizzBuzz の実装 1. ソースコード自身を文字列として得る 1. 自己複製 2. 自分自身を次の数字の形に整形する 2. フォント埋め込み 3. 以上を「実行可能なアスキーアート」として書く 3. 実行可能なアスキーアート 9
  • 10. 1. 自己複製 • Quine 、自己出力プログラム、Print Me! とも • ふつうの自己複製プログラム eval s=“ s = ‘eval s=‘ + s.inspect; puts(s) “ ※改行は分かりやすさのために入れています ※inspect: 文字列の前後に “ “ をつけるメソッド • self-descriptive FizzBuzz でも同じ構造 10
  • 11. 2. フォント圧縮 • 元データ (横 3 × 縦 5 × 約 15 文字 = 210 バイト) ### # ### ### # # ### ### ### ### ### ### ## # # ## # # # # # # # # # # # # # # # # # ## # # # # ### ### ### ### ### # ### ### ### ## # # # # # # # # # # # # # # # # # # # # # # # ### ### ### ### # ### ### # ### ### # ## ## ## # • # を 1、空白を 0 にして二進数に 111 010 111 111 101 111 111 111 111 111 111 110 000 00 0 101 110 001 001 101 100 100 101 101 101 100 101 101 11 1 101 010 111 111 111 111 111 001 111 111 111 110 101 01 0 101 010 100 001 001 001 101 010 101 001 100 101 101 10 1 111 111 111 111 001 111 111 010 111 111 100 110 011 11 1 • 10 進表示に (64 バイト) 1516849080105099949603183465996815374383250973658966149057739167 • to_s(36) で36進数に (41 バイト) 8hlduayacv7bl0a0h2m2d2ti20qewh0rrsjcmsgpr 11
  • 12. 3. 実行可能なアスキーアート 1. コード全体を %w( と ).join で囲む – %w(...) は文字列の配列のリテラル %w(foo bar)  [“foo”, “bar”] – .join は配列を文字列として連結するメソッド [“foo”, “bar”].join  “foobar” 2. eval する eval %w( pu ts 3. 自由に整形できる! puts “Hi” “H i” ).join## 12
  • 14. Qlobe: self-descriptive 地球儀プログラム v=0000;eval$s=%q~d=%!^Lcf<LK8, _@7gj*LJ=c5nM)Tp1g0%Xv.,S[<>YoP 4ZojjV)O>qIH1/n[|2yE[>:ieC "%.#% :::##" 97N-A&Kj_K_><wS5rtWk@*a+Y5 yH?b[F^e7C/56j|pmRe+:)B "##% ::##########" O98(Zh)'Iof*nm.,$C5Nyt= PPu01Avw^<IiQ=5$'D-y? "##: ###############" g6`YT+qLw9k^ch|K'),tc 6ygIL8xI#LNz3v}T=4W "# #. .####:#######" lL27FZ0ij)7TQCI)P7u }RT5-iJbbG5P-DHB<. " ##### # :############" R,YvZ_rnv6ky-G+4U' $*are@b4U351Q-ug5 " #######################" 00x8RR%`Om7VDp4M5 PFixrPvl&<p[]1IJ " ############:#### %#####" EGgDt8Lm#;bc4zS^ y]0`_PstfUxOC(q " .#############:##% .## ." /,}.YOIFj(k&q_V zcaAi?]^lCVYp!; " %% .################. #. " ;s="v=%04o;ev"% (;v=(v-($*+[45, ":####: :##############% : " ])[n=0].to_i;)% 360)+"al$s=%q#{ "%######. ######### " ;;"%c"%126+$s<< 126}";d.gsub!(/ "##########. #######% " |¥s|".*"/,"");; require"zlib"|| "########### :######. " ;d=d.unpack"C*" d.map{|c|n=(n|| ":#########: .######: . " )*90+(c-2)%91}; e=["%x"%n].pack " :#######% :###### #: " &&"H*";e=Zlib:: Inflate.inflate( " ######% .####% :: " &&e).unpack("b*" )[0];22.times{|y| " ####% %### " ;w=(Math.sqrt(1-( (y*2.0-21)/22)**(; " .###: .#% " ;2))*23).floor;(w* 2-1).times{|x|u=(e+ " %## " )[y*z=360,z]*2;u=u[ 90*x/w+v+90,90/w];s[( " #. " ;y*80)+120-w+x]=(""<< 32<<".:%#")[4*u.count(( " . " ;"0"))/u.size]}};;puts¥ s+";_ The Qlobe#{" "*18+ ( "# :#######" ;"Copyright(C).Yusuke End¥ oh, 2010")}";exit~;_ The Qlobe Copyright(C).Yusuke Endoh, 2010 14
  • 15. Qlobe の実装 1. 自己複製する 2. 地球儀をレンダリングして出力する – 世界地図が zlib 圧縮で埋め込まれてます 3. 邪魔な地球儀はショートカット演算子などで回避 “zlib” || “地球部分"  “zlib” “地球部分” && “H*”  “H*” 15
  • 16. 山手Quine t="+,m-n./mAm0o1p23a4q56r7sBt89u-t-1:v;A<w4x=y1z>[?]A^@CD_ z=27;eval$s=%w!c,s=["H+{K}8k->dXNpv-cD~@?(zhAi~>JOv<-;A(]oH+MFKs*+KOB825i$%QX9~P=HC{iIlj*Sh# CD_EsF`GHmIJbKa*l";eval$s=%w{F=%q{ceY8#<DvO1=x&t9CSOqMYkzH v=3U62LhUXhtnCx^{F=nuTtGG}@85_(xVvIWQ|Vllp[Gt22x&`^K3*ui;IW@O9-(`Z6V_T.E]%WHXYGa{O9A#msMgV{5 U.kCpz+Vo8hB.1AF&tq21+$/IrMY]U.aDd!-1y!4MMGQm6m?bYh($QMYpX R3XS/dxI8zM)XrbFom,$Msj8>=ca#i.yOqM-gtf2xH T#2VYW9Koq.)IjS:&n3f6$Q/@4-8m_[(HxaP>n*b]Ih/3`3T s4g,x1UlbNKH?>NzbisMn?sT@m3,F.Abb`xW!r%'%Ybee>xkUfjf[(*^Nd uG-C~3Bn)d.PSdX8 uvtft?;j%bsM^v&h NcaFzv7)uyD=lkc+eYn5&dN/%.|o@pD|BPi+a`rJCgg>?AE; Xo_"@hQh%Fx*q[iB7EM"suSG8GVOIzceg/O=4CL,d[-k]twgVP`&wcfaT` W~){4l9}","_m?PM(N5L <',.ht}f8B|*o8|Qg?:v '(@LY'1^KvIm8twKZHvU@:&FS)r[N1?t9k26*=tiLQw<Tq$l 2M)j8sFY?(HKzOrVCHO_694[Uq8g @i/i;tMBG#;-;B]rV[])`3'<os^. ]V1@Z3hnQ:cQ'b)>])-p }r'U[8hN 7`j6SW r-ZW m2 3n<ZaJ %C%g @@+DABEERjKj5Yt~&>xL OV(SA<=ok%m[iV#qt[&dJ7SIdB;/ VUnVIrH;hEJ*QWD"E+5)gfrmD"#E ~8BN`L#u?tE+CH$wM%*J px[D;A t%se'c waI. R; FIn( VUVq{0 6c Y]'1EV sqNd_V1yp8"].map{| XlNVv1j)^^ bCi_gw+s-V s|n=0;s.unpack("C*") .map{| c|n=n* 91+( c-1)%9 2};n}; e= "z=#{z =($*[i=0]?(z+1):z- J<?fWdtbnxRgJm4J.yHO_ay2e%rc Tj]ALVU'`V=]]W;x&9MP&g5zAVHR 1)%29};eval$s=%w"<<3 3<<$s[ 0,903] *3;1 4. time s{|y|b =" ";n=f= proc{|w|b<<e[i,w]; ?B,SZA+!_[0f!TUCv$Hin?-G7hAL BW6w1x+F#%@FZ<7!9;vNxsj6HW_O i+=w};t=s;f[4];z.dow nto(0){| a|a<1& &6.t imes {|x| y>1&&y<12&&c[n*60+y* Ao)H5cv`Ves-BQ"Z =K$_[o]Can(;1cJp 6-x-67]>0?(b<<32<<32):f[2]}while(0<n=(t/=38)%38)};f[4];y>12& &b[-28,28]=""<<33<<"*''#..(c). HV<:4x2,AnZgqvsy >VWDZdF-+^ 46Z^Z@<>1< cJ3E4GYSqGg7$ocX Yusuke.Endoh.2010";puts(b)}#c,s=["H+{K}8k->dXNpv-cD~@? (zhAi~>JOv<-;A(]oH+MFKs*+KOB825i 88=*`RVO*WskDY-# uj$t3$XP#U IH]regXHa_ >sta`lbL+=J3sL3e $%QX9~P=HC{iIlj*Sh#v=3U62LhUXhtnCx^{F=nuTtGG}@85_(xVvIWQ|Vllp[Gt22x&`^K3*ui;IW@O9-(`Z6V_T.E] BYxm/a0]lV1?M4WA u7jCGk`UBzB#*gOJ %WHXYGa{O9A#msMgV{5R3XS/dxI8zM)XrbFom,$Msj8>=ca#i.yOqM-gtf2xHT#2!*''#..(c).Yusuke.Endoh.2010 wHu#gQst^XB0VXjT imG<qb[s!* S#":,frD+N wn=nI<u;#dw*Y?"8 B#G[%YT$mvLd<gUd lN^6#bZX$S a#owd125V! 4d+zL5)I;JD-ToJ" uN?h9Braq+dG4Nr[ ynH,hS?nk4JD^/.q • 実行すると隣の駅名になる KS&kW@(62e]xb0j2(;4X[ROR2W Ifjf^3vhJ5jb5"sJ(4b6Ek1?Vx %s$^.yD.SY$':h[zd$D7o$n: Zp F= 2bHENRzBQhsd_7Im*HZG3xcx t#KdN4D3tEG%#F[1pbo_6C y;kI "Z`: ]^-/]HnWCrJ^=JBA9%gyIr %Xe,D'&Lmb:S<o_(b4VJ ji*bc# G'#ig: AQR[vp>>Jn;Mf$KRBf&7 [%X34447R.0v"Uz/4F "6Q+0>+1 N3OLCeMn ;8TQ>BHCW1";KrW,%P `C?@?)fz>c3B;r 8Q"QCjmU"3 SXd1Jt1qI; "G7HLO$I*6=fCC • 29 駅で元に戻る o!G6CSm1a] S(S#d#sa#2lXP& 4$L"^ir8_BEmkS vA!f@p!$A6 pE@#u%5QJda>[dT>cc4bYcAY)6uF 9%1C4f?GWDcZR`n,%>JrTqK$eHG2 W)B__.[JP+@2qlsWxug,O60@Nkj6VU#Gqp[fC%XOc`:C!-hbr3C0Dz2aLL RI%*4&Lto'OJxHohC=*H#sc][4ZwId0O,R]s<]D#ykgKY7Oc1`heSG/Xxj LA2aiV!<Q;8G/!8>GlX^T4P-/.oIyvR>kPyJ;lXD1r8n5gHPeuA4%j8*0> Iu^>CRxHz3HYX*#n,t_EjxBRbgFH kj:PmmNq3MA10LXwbAW&S^/0_x,H 4d5"_9>K!n6*b(ij`:HQRKf]EJoM NwY>5Si'd#'5BuS8[sF`_[bf9Z<W vdK3HiV+1L.jL*%;&g.G#?S5:Xh$ /gWw#1U-lHTo"?_dxYHC&UGLa)yn %zdU1KPkrE wXsKbTBBix xh=#es7os:-9<`3Olf(!YN!hK?1a,2UMJ^`IC)oc8Z/TipLWy(%p0qUZoO ;W#bB%8=9CZvoU$eG;kXt[hewZnV!(B(u-[L3)l,6C%3.?u?znQyMgw31s [s4Ne+XNPNcpmuaJ<] Hd:/;va-yp4)mU.&Vr Z@*N3mTZX)0]%^]0d6 a'@njg`2DJ;stf^WTr 3y%gWte5;+Q>ZbENlv rK!4M=y6IQ27&IJm>n w57+;)s=Foy<4pdw5i lSDhJRyao%_Wx+[lx6 D8Goea3uRPpunFulWq 0*3GoGaJyAHF$#bJca 5&Z0K'r[o,K*"/^jv6 m08,PTZy$g?eX[aN4j J]AkXcV72;!};f=0;F .unpack("C*").map{ |c|f=f*89+((c-2)%9 0-1)};require'zlib ';t=t.split*"";$*[0]?(t[/([* -K]+.)([*-K]+.)$/];t=$2+$`+s =$1):(s=t[/.+?[L-z]/];t=$'+s );f=Zlib::Inflate.inflate(Ma rshal.dump(f)[7..-1] );S=%{ t="# {t}";eval$s=%w{#$s}* "";%|}+F*9;P=proc{pu ts(S.s lice!(0, 58));P};P[][][][s. upcase.unpack("C*" ).map{|c |c-=c>92?4 3:42;;P[][][20.t imes{|n|puts(("% 029b"%("¥0 "+f[60*c+3*n ,3]).unpack("N ")[0]).gsub( /./){$&<"1"? (S.slice!(0,2) ):(32.chr*2) })}]}][];puts(*["+"+"-"* 25,"|,##,(c),Yusuke,Endoh,20 09".split(",").join(32.chr)].map{|l|S.slice!(0,32)+l})}*"" ;%|ceY8#<DvO1=x&t9CSOqMYkzHU.kCpz+Vo8hB.1AF&tq21+$/IrMY]U. aDd!-1y!4MMGQm6m?bYh($QMYpXs4g,x1UlbNKH?>NzbisMn?sT@m3,F.A bb`xW!r%'%Ybee>xkUfjf[(*^NdXo_"@+------------------------- hQh%Fx*q[iB7EM"suSG8GVOIzceg/O=4| ## (c) Yusuke Endoh 2009 16
  • 17. 自己相似 Quine eval$s=%w'k=0013;f=proc{|x,y,s|x*x+y*y*4<36864&&(u,v=x.ro eval$s=%w'k=0026;f=proc{|x,y,s|x*x+y*y*4<36864&&(u,v=x.ro eval$s=%w'k=0054;f=proc{|x,y,s|x*x+y*y*4<36864&&(u,v=x.ro eval$s=%w'k=0067;f=proc{|x,y,s|x*x+y*y*4<36864&&(u,v=x.ro eval$s=%w'k=0136;f=proc{|x,y,s|x*x+y* eval$s=%w'k=0000;f= und,y.round;x.abs>21+s||y.abs>4+s||(x*x+(y*2+6)**2<4?f[x* y*4<36864&&(u,v=x.round,y.round;x.abs>21+ proc{|x,y,s|x*x+y*y*4<36864 96,y*96+288,s*192]:u*u<441&&v*v<25&&"36effv0qbzox5c3npa19 s||y.abs>4+s||(x*x+(y*2+6)**2<4?f[x*96,y*96+2 &&(u,v=x.round,y.round;x.abs>21 1hhgzrio5b3640nv9g9jzvnm8a67su".to_i(36)[u-v*41+143]>0))} 88,s*192]:u*u<441&&v*v<25&&"36effv0qbzox5c3npa1 +s||y.abs>4+s||(x*x+(y*2+6)**2<4?f[ ;k=(k+($*[0]||0).to_i)%99;t=("eval$s=%%w%ck=%04o;"%[39,k] 91hhgzrio5b3640nv9g9jzvnm8a67su".to_i(36)[u-v*41+14 x*96,y*96+288,s*192]:u*u<441&&v*v<25&&" ;k=(k+($* )<<($s[7,530]<<35<<35)*9;s=8/96**(1-k.to_f/98);o=(-11..11 3]>0))};k=(k+($*[0]||0).to_i)%99;t=("eval$s=%%w%ck=%0 36effv0qbzox5c3npa191hhgzrio5b3640nv9g9jz [0]||0).to_i)%99; ).map{|j|(-28..28).map{|i|f[i*s,j*s-36*(8-s)/95,s/4]??a:3 4o;"%[39,k])<<($s[7,530]<<35<<35)*9;s=8/96**(1-k.to_f/9 vnm8a67su".to_i(36)[u-v*41+143]>0))};k=(k+( t=("eval$s=%%w%ck=%04 2.chr}*""}*10.chr;o.sub!(/aaaa((#{"Quine";(s=92.chr)+?s}+ 8);o=(-11..11).map{|j|(-28..28).map{|i|f[i*s,j*s-36*(8- $*[0]||0).to_i)%99;t=("eval$s=%%w%ck=%04o;"%[ o;"%[39,k])<<($s[7,530]<< 2.chr}*"" a{1,3})*#{s+?s}*)#{s+?z}/){39.chr+%(*"")+$1.tr(?a,?;)};o. s)/95,s/4]??a:32.chr}*""}*10.chr;o.sub!(/aaaa((#{"Quine"; 39,k])<<($s[7,530]<<35<<35)*9;s=8/96**(1-k.to_f 35<<35)*9;s=8/96**(1-k.to_f }*10.chr;o.su gsub!(/a/){t.slice!(0,1)};puts(*o)##f=proc{|x,y,s|x*x+y*y (s=92.chr)+?s}+a{1,3})*#{s+?s}*)#{s+?z}/){39.chr+%(*"")+$ /98);o=(-11..11).map{|j|(-28..28).map{|i|f[i*s, /98);o=(-11..11).map{|j|(-2 b!(/aaaa((#{"Qu gsub!(/a/){ *4<36864& 1.tr(?a,?;)};o.gsub!(/a/){t.slice!(0,1)};puts(*o)##f=proc j*s-36*(8-s)/95,s/4] t.sli ??a:32.chr}*""}*10.c 8..28).map{|i|f[i*s,j*s-36*(8 ine";(s=92.chr)+? &(u ,v=x.roun ce!(0,1)};p d,y.round ;x.abs>2 s}+a{1,1 + 32.chr}*""}* {|x,y,s|x*x+y*y*4<36864&&(u,v=3})*#{s hr;o.sub!(/aaaa((#{" uts (*o";(s=92.chr)+?s}+a{1 -s)/95,s/4]?Quine x.round,y.round;x.abs>21+ ?a: s||y.abs> ) 4+s||(x*x +( 10.chr;o.sub!(/aaaa((#{"Quine s||y.abs>4+s||(x*x+(y*2+6)**2<4?f[x*96,y*96+288,s*192]:u* ,3})*#{s+?s}*)#{s+?z pro }/){39.chr+%(*"")+$1 ##f= y*2 +?s}*)#{s+?z}/){3 +6)**2<4? c f[x*96,y* 96 +y,s| ,sx*x+ 2]: u*u<441 &&v* v< 25&&"36ef u<441&&v*v<25&&"36effv0qbzox5c3npa191hhgzrio5b3640nv9g9jz .tr(?a,?;)};o.gsub!(/a/){t.slice!(0,1)};puts(*o {|x, ";(s=92.chr)+?s}+a{1,3})*#{ 288 9.chr+%(*"")+$1 *19 y*y* 4<36864&&(u ,v=x.rou n fv0qbzox5 c3 npa19 1hd;x. rio 5b3 640 nv9g9jz vnm8a67su vnm8a67su".to_i(36)[u-v*41+143]>0))};k=(k+($*[0]||0).to_i )##f=proc{|x,y,s|x*x+y*y*4<36864&&(u,v=x.round, d,y. rouns+?s}*)#{s+?z}/){39.chr+% .tr(?a,?;)}21+s||y.abs hgz abs> >4+s||(x *)%99;t=("eval$s=%%w%ck=%04o;"%[39,k])<<($s[7,530]<<35<< ".to_i(36 )[ +6)* 41*2<4 ;o. 0)) };k *96+28 8,s*19 2 x+ y.round;x.abs>21+s||y.abs>4+s||(x*x+(y*2+6)** (y*2 u-v* (*"")+$1.tr(?a,?;)};o.g=(k +14 ?f[x *96,y 3]> +($*[0]|| ]35)*9;s=8/96**(1-k.to_f/98);o=(-11..11).map{|j|(-28..28p 0).to_i)% 99;t=(" ev al$s=% %w% ck= %04 fv0qbz 9,k])<<($ :u 2<4?f[x*96,y*96+288,s*192]:u*u<441&&v*v<25& *u<4 41&&sub!(/a/){t.slice!(0, o;"%[3 ox5c3n v*v< 25&& "36ef a ).map{|i|f[i*s,j*s-36*(8-s)/95,s/4]??a:32.chr}*""}*10 s[7,530]< 191hhgz rio5 &"36effv0qbzox5c3npa191hhgzrio5b3640nv9g9 1)};puts(*o)##f b364 0nv9 g9jzv nm8a <35<<35)* 67su".to_ g i .chr;o.sub!(/aaaa((#{"Quine";(s=92.chr)+?s}+a{1,3}) 9;s=8/96**(1-k.to_f/98);o=(-11..11).map{|j|(-28..28).map{ (36)[u -v*4 jzvnm8a67su".to_i(36)[u-v*41+143]>0))}; ($*[ sub!(/a/){t.s1+14lice!(0,1)};p =pr 3]>0 ))};k =(k+ uts(*o)##f=pr o 0 |i|f[i*s,j*s-36*(8-s)/95,s/4]??a:32.chr}*""}*10.chr;o.sub *#{s+?s}*)#{s+?z}/){39.chr+%(*"")+$1.tr(?a,?;)};o ]||0). to_i c{|x,y,s|x*x+)%99y*y*4<36864&& k=(k+($*[0]||0).to_i)%99;t=("eval$s %w%c ;t=( "eval $s=% (u,v=x.round, y k=%04o;"%.round;x.abs> !(/aaaa((#{"Quine";(s=92.chr)+?s}+a{1,3})*#{s+?s}*)#{s+?z .gsub!(/a/){t.slice!(0,1)};puts(*o)##f=proc{| [39 ,k])<<($s[721+s||y.abs>4 =%%w%ck=%04o;"%[39,k])<<($s[7,5 +s||(x*x+(y*2 ,530 ]<<35 <<35 )*9;s=8/ + }/){39.chr+%(*"")+$1.tr(?a,?;)};o.gsub!(/a/){t.slice!(0,1 x,y,s|x*x+y*y*4<36864&&(u,v=x.round,y.round 6)**2<4?f[x*9 30]<<35<<35)*9;s=8/96**(1-k 192]:u*u<441& 6,y*96+288,s* oc{|x,y,s|x*x+y*y* .to_f/98);o=(-1'*"" & 96**(1-k.to_f/98);o=(-11..11).map{|j|(-28..28).map{|i'*"" )};puts(*o)##f=proc{|x,y,s|x*x+y*y*4<36864&&(u,v=x.ro'*"" v*v<25&&"36ef ;x.abs>21+s||y.abs>4+s||(x*x+(y*2'*"" 4<36864&&(u,v=x.r'*"" fv0qbzox5c3np a191hhgz'*"" ;;; 17
  • 18. 15quzzle Quine でパネル移動後の盤面が出てくる eval$s=%w[b=0 x40e1359a76cb d8f2;i=(m=0.. 15).find{|i|1 >b&m=15<<4*i} ;t=m|n=m<<4*o =("AdABrBlBAu A"=~/(.)#{ARG V*''}¥1/||04| |0)-4;(n<1||n >1<<64||[255< <12]&[t>>040| |___________2 |__________15 |___________8 |__________13 |0,t>>16,t]!= [])?t=0:i+=o; ;s="eval$s=%% w[b=0x%016x"% (b^=t.&b|m&b> >o*4)+$s.gsub (/(¥|_+¥d+)+/ ,'')[/;.*/]+" ]*''||0"<<92| |1;z=s=s.scan (/.{13}/);3.t imes{|j|s[(i| |__________11 |__________12 |___________6 |___________7 |0)/4*8+i+j*4 ,0]=m=(z=32.c hr)*13};c=b;4 .times{puts(( 0..3.times{pu ts((s.slice!( 0,4)*z).rstri p)}).map{j=c% 16;c/=16;;(0| |0)<(j)?"|"+j .to_s.rjust(1 2,"_"):m}*(z| |__________10 |___________9 |___________5 |___________3 |0),z)};b==0x fedcba9876543 21&&("%b"%"1t v7c1th0wylel7 3ba35knw3t".t o_i(36)).tr(" 01",".#").sca n(/.{25}/){pu ts$&}]*''||0¥ |___________1 |__________14 |___________4 18
  • 19. 関連研究 • International Obfuscated C Code Contest (IOCCC) – みにくい C コードを書くコンテスト 円周率計算プログラム 電卓プログラム (hou [2011]) (westley [1988]) #include <stdio.h> #include <math.h> #define _ -F<00||--F-OO--; (略) int F=00,OO=00;main(){F_OO(); printf("%1.3f¥n",4.*-F/OO/OO);}F_OO() int main(int argc,char** argv){ { if(argc<2){ _-_-_-_ puts( _-_-_-_-_-_-_-_-_ usage: calculator 11/26+222/31 _-_-_-_-_-_-_-_-_-_-_-_ +~~~~~~~~~~~~~~~~~~~~~~~~calculator-¥ _-_-_-_-_-_-_-_-_-_-_-_-_-_ ! 7.584,367 ) _-_-_-_-_-_-_-_-_-_-_-_-_-_-_ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ _-_-_-_-_-_-_-_-_-_-_-_-_-_-_ ! clear ! 0 ||l -x l tan I (/) | _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_ _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_ ! 1 | 2 | 3 ||l 1/x l cos I (*) | _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ _-_-_-_-_-_-_-_-_-_-_-_-_-_-_ ! 4 | 5 | 6 ||l exp l sqrt I (+) | _-_-_-_-_-_-_-_-_-_-_-_-_-_-_ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ _-_-_-_-_-_-_-_-_-_-_-_-_-_ ! 7 | 8 | 9 ||l sin l log I (-) | _-_-_-_-_-_-_-_-_-_-_-_ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(0 _-_-_-_-_-_-_-_ ); _-_-_-_ } } return 0; } 19
  • 20. 超絶技巧プログラミングの実践 テーマ 1: self-descriptive な Ruby プログラム テーマ 2: 文字を制限した Ruby プログラム 20
  • 21. 使える文字を制限して Ruby を書く • 今日のテーマ: 小文字アルファベット(と空白)だけ • 実装方針 – 実行したいコードの文字列を構築し、eval する eval “code” • 説明の順序 1. アルファベット(大文字含む)+数字だけで書く (Hamaji [2008]) 2. 大文字を排除する 3. 数字を排除する 21
  • 22. コード文字列を構築する • 問題: 文字列リテラルは使えない クォート使用不可 “code” • 解決: 文字列を返す組み込み関数を使う –例 String nil  “” – nilを文字列に型変換する:空文字列が得られる – 空文字列に ASCII code で文字を連結していく “”.concat(65)  “A” “A”.concat(66)  “AB” 22
  • 23. ピリオドなしで concat を呼び出す ピリオド・カッコ • 問題: メソッドが呼び出せない 使用不可 “”.concat(65) • 解決: String のメソッドからはピリオドなしで呼べる – Ruby ではカッコは常に省略可能 class String 空文字列からコードを def generate 構築するメソッドを定義する concat 65 concat 66 新たな課題: end この構築メソッド自身を end どう呼び出すか? “”.generate 23
  • 24. コード構築メソッドを起動する • Ruby の for 文 for 変数 in コレクション do ... end 構文糖 コレクション.each do |変数| ... end ∴ コード構築メソッドを each という名前にすれば ピリオドなしで呼び出せる “”.each ≒ for elem in “” do end 24
  • 25. 第一段階: アルファベットと数字で Ruby 例: コード文字列 “p 1” を構築・ eval するコード class String def each 文字列を構成する様子 concat 112 “” concat 32 concat 112 concat 49 eval self “p” concat 32 exit end “p ” concat 49 end for i in “p 1” eval String nil do end 25
  • 26. class String 大文字を排除する def each ... • String の ”S” が 2 箇所 end end • class String の箇所 for i in – String クラスには定義できない String nil do end – トップレベルは Object クラス  トップレベルに定義すればよい public def each • String nil の箇所 clear – 文字列を返す別のメソッドにする ... – String#clear で空文字列に end for i in String nil do inspect do end 26
  • 27. 第二段階: 小文字 alphabetと数字で Ruby 例: “1” を出力するコード class String public def each def each concat 112 clear concat 32 concat 112 concat 49 concat 32 eval self concat 49 exit eval self end exit end end for i in for i in String nil do inspect do end end 27
  • 28. 数字を排除する(1) • 欲しい数字の長さの文字列を作り size を呼ぶ – 例: 8 を生成するコード clear # “” concat size # “¥0” concat self # “¥0¥0” concat self # “¥0¥0¥0¥0” concat self # “¥0¥0¥0¥0¥0¥0¥0¥0” size # 23 = 8 が得られる • 今まで構築してきたコードが消えてしまう! 28
  • 29. 数字を排除する(2) • 例外処理の構文 現在の self “...” begin A ensure B end – Java の try { A } finally { B } concat begin みたいなもの dup • 式全体が A の評価結果を返す ensure concat begin – A を評価し 65 を作る ensure – B を評価し clear end – B の評価結果を捨てて end A の評価結果を返す構文 • 文字列の先頭に 1 文字追加 するイディオムが作れる “A...” 新しい self 29
  • 30. loop do break public end catch inspect do def each loop do break clear end concat begin dup ensure clear concat concat concat concat size loop do break concat concat size end loop do break concat concat size end 小文字アルファベットだけで Ruby を書く loop do break concat size end concat begin size ensure clear end end concat begin dup ensure clear concat concat concat concat concat concat size loop do break concat size end concat begin size ensure clear end end concat begin dup ensure clear loop do break concat concat size end concat concat concat concat size concat concat concat size concat begin size ensure clear end end concat begin dup ensure clear loop do break concat concat size end concat concat concat size loop do break concat concat size end concat concat concat size loop do break public end concat begin size ensure clear end end concat begin dup ensure clear loop do break concat concat size end loop do break concat concat size end concat concat concat concat size loop do break concat concat size end catch inspect do def each concat begin size ensure clear end end concat begin dup ensure clear loop do break concat concat size end concat concat concat size loop do break concat concat size end loop do break concat concat size end loop do break clear end loop do break concat concat size end loop do break concat size end concat begin size ensure clear end end concat begin dup ensure clear loop do break concat concat size end loop do break concat concat size end concat begin dup ensure clear concat concat concat size loop do break concat concat size end loop do break concat concat size end loop do break concat size end concat begin size ensure clear end end concat begin dup ensure clear concat concat concat concat size concat concat concat concat concat concat size concat begin size ensure clear end end concat begin dup ensure clear concat concat concat size loop do break concat concat size end concat concat concat size loop do break concat concat size end concat begin size ensure clear end end concat begin dup ensure clear loop do break concat concat size end concat concat concat size loop do break concat concat size end loop do break concat concat size end loop do break concat concat size end loop do break concat concat size end loop do break concat size end concat begin size ensure clear end end concat begin dup ensure clear loop do break concat concat size end concat concat concat size loop do break concat size end loop do break concat concat size end concat concat concat size concat begin size ensure clear end end concat begin dup ensure clear loop do break concat concat size end concat concat concat size concat begin size ensure clear end end loop do break concat concat size end concat concat concat size concat begin size ensure clear end end concat begin dup ensure clear loop do break concat concat size end concat concat concat concat size concat begin dup ensure clear concat concat concat size loop do break concat size end concat begin size ensure clear end end concat begin dup ensure clear concat concat concat concat size concat concat concat concat size concat concat concat concat concat concat size concat begin size ensure clear end end concat begin dup ensure clear concat concat concat concat size loop do break concat concat size end loop do break concat concat size end loop do break concat size end loop do break concat size end concat begin size ensure clear end end concat begin dup ensure clear loop do break concat concat size end loop do break concat concat size end concat concat concat concat size loop do break concat concat size end loop do break concat size end concat begin size ensure clear end end concat begin dup ensure clear loop do break concat concat size end loop do break concat concat size end concat concat concat size concat concat concat size concat begin size ensure clear end end concat begin dup ensure clear loop do break concat concat size end loop do break concat concat size end concat concat concat size concat concat concat size loop do break concat size end concat begin size ensure clear end end concat begin dup ensure clear loop do break concat concat size end loop do break concat concat size end concat concat concat concat concat size concat begin size ensure clear end end loop do break eval self end loop do exit end end end for each in inspect do 30 copyright mmxii yusuke end o h
  • 31. 関連研究: 他の文字制限の例 _=[*' '..?~]*'';$><<_[(___=_=~/@/ • 記号だけ (kurimura [2008]) ).+_=~/¥(/]+_[(__=_=~/_/).+_=~/&/ ]+_[__+@@_=_=~/¥-/]+_[__+@@_]+_[( @_=_=~/~/)-@@_=_=~/¥//]+", "+_[ @_.-_=~/'/]+_[@_-@@_]+_[@_.-_=~ /,/]+_[__.+_=~/¥-/]+_[__.+_=~/%/ ]+?!+$/ • 数字(+ require)だけ require "1234567890" 316805813369061470447252554255354 816767578747985092956934801232229 450578663292118901228453190669621 8369564670777459615871118090530 require "_" • アンダースコア(+ require) ____ _ _____ ____ __ ____ ____ __ ___ ____ __ __ _ ______ _____ だけ ___ _ _ ___ _____ ______ ____ _ _ ____ _ _ ____ _ ____ __ __ ___ _ ______ ___ ____ __ ______ ____ _ ____ ____ __ _ ____ _ _ ___ _____ _____ _ ______ ____ _ ______ _____ 31
  • 32. 関連研究: 他言語での文字制限の例 • Perl: 記号だけ (Takesako [2005]) Quiz: これは何をするプログラムでしょう? まとめ  Let’s 予約語プログラミング♪ #!/usr/bin/perl  Perl 以外の言語でも実装できますか? sin cos and s qq qx xor s x x print uc chr lc  awk ? ord qq sleep times x xor int log cos xor eval  Haskell ? Lisp ? and eval and print uc chr ord scalar reverse   ML ? qq exit binmode xor qq write qw xor print uc  Perl → OK ! chr ord scalar reverse qw tell my print  PHP ?  Python ? 挑戦者求む!  Ruby ? 正解 → 標準出力に “LLDN” という文字列を出力するプログラム 2005/08/27 Lightweight Language Day and Night 4 2005/08/27 Lightweight Language Day and Night 18 • Javascript – 記号だけ (Hasegawa [?]) – 顔文字だけ (Hasegawa [?]) 32
  • 33. 目次 • 背景: 近年のプログラミングの問題 • 提案: 超絶技巧プログラミング – 実践1: self-descriptive な Ruby プログラム – 実践2: 文字を制限された Ruby プログラム • まとめ 33
  • 34. まとめ • 超絶技巧プログラミングを紹介した – 実用性を無視して「美しい」プログラミング • みなさんもいかがでしょうか – IOCCC開催中  – 9/15 まで 34