Top Banner
超超超超 Ruby Programming Esoteric, Obfuscated Ruby Programming 遠遠遠遠 Yusuke Endoh
33

超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

Feb 10, 2017

Download

Technology

mametter
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

超絶技巧 Ruby ProgrammingEsoteric, Obfuscated Ruby Programming

遠藤侑介Yusuke Endoh

Page 2: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

Who am I?• Yusuke Endoh 遠藤侑介– twitter: @mametter– hatena: http://d.hatena.ne.jp/ku-ma-me/ in Japanese– blogger: http://mamememo.blogspot.com/ in English

• A committer for Ruby and RubySpec– 1.9.2 assistant release manager

• An esoteric programmer

2

Page 3: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

Esoteric Programming• 普通の人 normal programmer

• Esoteric Programmer

• 参考 : ゴルファー cf. code-golfer (14B)

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].reversed,be="whydoes","crypto";:make. | %.mains..tr'eams',be.delete(d)

puts “Hello, world!”

#!../s/grb -eh

http://d.hatena.ne.jp/kurimura/20090929/1254257912

3

Page 4: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

Esoteric Programming Language (esolang)

• 読み書きしにくいように作られた言語obfuscated, confusing and unreadable programming language

– esoteric: 難解な、深遠な、秘伝的な、奥義に達した– ex) brainf**k

• 共通の特徴 : 奇妙な制約common feature: bizarre constraint– 使える文字 bizarre kind of character used

– 使える命令 bizarre instruction set

– 命令順序や文字配置 bizarre execution order and placement

+++++++++[>++++++++>+++++++++++>+++++<<<]>.>++.+++++++..+++.>-.------------.<++++++++.--------.+++.------.--------.>+.

Hello world in brainf**k

4

Page 5: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

Theme: Enjoy esolang with Ruby!• 制約を課せば Ruby も esolang として楽しめる

Ruby with constraint can be an esolang– 1. 使用文字制約に勝つ ( ○○文字だけで Ruby を書ける

か?) beat “character constraints” (Can you write Ruby with __ character-only?)

– 2. 文字配置制約に勝つ (アスキーアート Quine ) beat “shape constraints” (ASCII-art Quine)

• 見所 Highlights

– むだに深淵な背景理論esoteric theory

– 勝つためなら何でもするdirty hack

• ゲーデル数 Gödel numbering• コルモゴロフ複雑性 Kolmogorov complexity• チューリング完全性 Turing completeness

• Ruby の黒魔術 Ruby’s black magic• コードゴルフ code golf• 文法や意味論の悪用 abuse of syntax/semantics

5

Page 6: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

1. Hello world with __ Character-only

6

Page 7: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

Hello world with Number only

任意のプログラムが書けます you can write not only “Hello, world!” but also any program

require "1234567890"

3168058133690614704472525542553548167675787479850929569348012322294505786632921189012284531906696218369564670777459615871118090530

7

Page 8: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

実装 internal

• ゲーデル数化 Encoding: Gödel numbering

• Ruby の黒魔術 Ruby’s black magic

• you can install: gem install 1234567890_

Hello world with number only

8

Page 9: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

ゲーデル数による符号化 Gödel numberingHello world with number only

9

Page 10: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

黒魔術 Ruby’s black magic

• コードに書かれただけの数字の参照を引っぱり出すHow to gain number written in code directly

– GC.disable– at_exit– ObjectSpace.each_object(Bignum)– eval

1.8 と 1.9 両方で動く both 1.8 and 1.9 can run this

JRuby でも動く(が – X+O オプションが必要) JRuby can also run this, but needs -X+O option; uncool

Hello world with number only

10

Page 11: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

Hello, world with underscore only

require "_"____ _ _____ ____ __ ____ ______ ___ ____ __ __ _ ______ ________ _ _ ___ _____ ______ ____ __ ____ _ _ ____ _ ____ __ __ ____ ______ ___ ____ __ ______ _____ ____ ____ __ _ ____ _ _ ________ _____ _ ______ ____ _______ _____

11

Page 12: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

実装 internal

• プログラムのゲーデル数化 (“ number only” と同じ)also uses Gödel numbering

• ゲーデル数の 6 進数表記をアンダースコアで表すrepresent each base-6 digit of Gödel number as length of underscores

• Ruby の有名黒魔術 : method_missingRuby’s famous black magic: method_missing

• you can install: gem install _

Hello world with underscore only

12

Page 13: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

なぜ 6 進数? why base-6?Hello world with underscore only

13

Page 14: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

Hello world with purely Alphabet onlyclass Stringdef inspectconcat begin dup ensure replace String nilconcat concat concat concat sizeconcat concat sizeconcat concat sizeconcat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat concat concat concat concat sizeconcat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat sizeconcat concat concat concat sizeconcat concat concat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat sizeconcat concat concat sizeconcat concat sizeconcat concat concat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat sizeconcat concat sizeconcat concat concat concat sizeconcat concat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat sizeconcat concat concat sizeconcat concat sizeconcat concat sizeconcat concat sizeconcat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat sizeconcat concat sizeconcat concat concat sizeconcat concat sizeconcat concat sizeconcat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat concat concat concat concat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat concat sizeconcat concat sizeconcat concat concat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat sizeconcat concat concat sizeconcat concat sizeconcat concat sizeconcat concat sizeconcat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat sizeconcat concat concat sizeconcat concat sizeconcat concat concat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat sizeconcat concat concat sizeconcat concat sizeconcat concat concat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat sizeconcat concat concat concat sizeconcat concat concat sizeconcat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat concat concat sizeconcat concat concat concat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat concat concat sizeconcat concat sizeconcat concat sizeconcat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat concat concat concat concat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat sizeconcat concat sizeconcat concat concat concat sizeconcat concat sizeconcat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat sizeconcat concat sizeconcat concat concat sizeconcat concat concat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat sizeconcat concat sizeconcat concat concat sizeconcat concat concat sizeconcat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat sizeconcat concat sizeconcat concat concat concat concat sizeconcat begin size ensure replace String nil end endeval selfexit end endcopyright MMX Yusuke Endoh p String nil

• require がないthere is no “require”

class Stringdef inspectconcat begin dup ensure replace String nilconcat concat concat concat sizeconcat concat sizeconcat concat sizeconcat sizeconcat begin size ensure replace String nil end endconcat begin dup ensure replace String nilconcat concat concat concat concat concat sizeconcat sizeconcat begin size ensure replace String nil end end

14

Page 15: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

実装 internal

• 自分で読んでくださいno time to explain; please read code by yourself– http://d.hatena.ne.jp/ku-ma-me/20100709/p1

– You can read it because it is purely written in Ruby that you know!

• shinh さんのアイデアがベースbased on shinh’s idea (Shin’ichiro Hamaji)– アルファベットと数字だけ

Pure Ruby with Alphabet and Number only– http://d.hatena.ne.jp/shinichiro_h/20081109#1226217059

Hello world with purely alphabet only

15

Page 16: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

対「文字制約」まとめsummary of anti-character constraints

• Ruby は使用文字制約に結構強いRuby beats character constraints

• おまけ : 1.8 と 1.9 は意外に互換である1.9 is more compatible with 1.8 than you think

• 未解決問題 open problem

– 小文字アルファベットだけ lower-case alphabet only

– 大文字だけ(不可能?) upper-case only (impossible?)

– 「記号だけ」は解決済み FYI: “punctuation only” was resolvedhttp://www.kurimura.com/rsencode/

16

Page 17: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

2. Ruby for Quine in ASCII-art

17

Page 18: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

Quine とは What’s Quine?

• 自分自身を出力するプログラム a program that outputs itself

• 実装の基本 implementation basis

– 手順 1. 自分自身を文字列として再構成するStep 1. construct a string that is itself

– 手順 2. その文字列を出力する Step 2. print it

• 出力前に整形すると変な Quine ができるwe can write “artistic” Quine by shaping it before printing

eval s="puts'eval s='+s.inspect"

18

Page 19: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

山手 Quine Yamanote Quine

• 実行すると隣の駅名になるThis program transforms the next station name of Japanese Yamanote Loop Rail line

• 29 駅で元に戻るwe need invoke ruby 29 times (stations) once– 起動速度重要

invoking speed matters

– JRuby is 10x slower than MRI (3.3sec vs. 33sec)

z=27;eval$s=%w!c,s=["H+{K}8k->dXNpv-cD~@?(zhAi~>JOv<-;A(]oH+MFKs*+KOB825i$%QX9~P=HC{iIlj*Sh#v=3U62LhUXhtnCx^{F=nuTtGG}@85_(xVvIWQ|Vllp[Gt22x&`^K3*ui;IW@O9-(`Z6V_T.E]%WHXYGa{O9A#msMgV{5R3XS/dxI8zM)XrbFom,$Msj8>=ca#i.yOqM-gtf2xH T#2VYW9Koq.)IjS:&n3f6$Q/@4-8m_[(HxaP>n*b]Ih/3`3TuG-C~3Bn)d.PSdX8 uvtft?;j%bsM^v&h NcaFzv7)uyD=lkc+eYn5&dN/%.|o@pD|BPi+a`rJCgg>?AE;W~){4l9}","_m?PM(N5L <',.ht}f8B|*o8|Qg?:v '(@LY'1^KvIm8twKZHvU@:&FS)r[N1?t9k26*=tiLQw<Tq$l]V1@Z3hnQ:cQ'b)>])-p }r'U[8hN 7`j6SW r-ZW m2 3n<ZaJ %C%g @@+DABEERjKj5Yt~&>xL~8BN`L#u?tE+CH$wM%*J px[D;A t%se'c waI. R; FIn( VUVq{0 6c Y]'1EV sqNd_V1yp8"].map{|s|n=0;s.unpack("C*") .map{| c|n=n* 91+( c-1)%9 2};n}; e= "z=#{z =($*[i=0]?(z+1):z-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];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*6-x-67]>0?(b<<32<<32):f[2]}while(0<n=(t/=38)%38)};f[4];y>12& &b[-28,28]=""<<33<<"*''#..(c).Yusuke.Endoh.2010";puts(b)}#c,s=["H+{K}8k->dXNpv-cD~@? (zhAi~>JOv<-;A(]oH+MFKs*+KOB825i$%QX9~P=HC{iIlj*Sh#v=3U62LhUXhtnCx^{F=nuTtGG}@85_(xVvIWQ|Vllp[Gt22x&`^K3*ui;IW@O9-(`Z6V_T.E]%WHXYGa{O9A#msMgV{5R3XS/dxI8zM)XrbFom,$Msj8>=ca#i.yOqM-gtf2xHT#2!*''#..(c).Yusuke.Endoh.2010

t="+,m-n./mAm0o1p23a4q56r7sBt89u-t-1:v;A<w4x=y1z>[?]A^@CD_CD_EsF`GHmIJbKa*l";eval$s=%w{F=%q{ceY8#<DvO1=x&t9CSOqMYkzHU.kCpz+Vo8hB.1AF&tq21+$/IrMY]U.aDd!-1y!4MMGQm6m?bYh($QMYpXs4g,x1UlbNKH?>NzbisMn?sT@m3,F.Abb`xW!r%'%Ybee>xkUfjf[(*^NdXo_"@hQh%Fx*q[iB7EM"suSG8GVOIzceg/O=4CL,d[-k]twgVP`&wcfaT`2M)j8sFY?(HKzOrVCHO_694[Uq8g @i/i;tMBG#;-;B]rV[])`3'<os^.OV(SA<=ok%m[iV#qt[&dJ7SIdB;/ VUnVIrH;hEJ*QWD"E+5)gfrmD"#EXlNVv1j)^^ bCi_gw+s-VJ<?fWdtbnxRgJm4J.yHO_ay2e%rc Tj]ALVU'`V=]]W;x&9MP&g5zAVHR?B,SZA+!_[0f!TUCv$Hin?-G7hAL BW6w1x+F#%@FZ<7!9;vNxsj6HW_OAo)H5cv`Ves-BQ"Z =K$_[o]Can(;1cJpHV<:4x2,AnZgqvsy >VWDZdF-+^ 46Z^Z@<>1< cJ3E4GYSqGg7$ocX88=*`RVO*WskDY-# uj$t3$XP#U IH]regXHa_ >sta`lbL+=J3sL3eBYxm/a0]lV1?M4WA u7jCGk`UBzB#*gOJwHu#gQst^XB0VXjT imG<qb[s!* S#":,frD+N wn=nI<u;#dw*Y?"8B#G[%YT$mvLd<gUd lN^6#bZX$S a#owd125V! 4d+zL5)I;JD-ToJ"uN?h9Braq+dG4Nr[ ynH,hS?nk4JD^/.qKS&kW@(62e]xb0j2(;4X[ROR2W Ifjf^3vhJ5jb5"sJ(4b6Ek1?Vx%s$^.yD.SY$':h[zd$D7o$n: Zp F= 2bHENRzBQhsd_7Im*HZG3xcxt#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=fCCo!G6CSm1a] S(S#d#sa#2lXP& 4$L"^ir8_BEmkS vA!f@p!$A6pE@#u%5QJda>[dT>cc4bYcAY)6uF 9%1C4f?GWDcZR`n,%>JrTqK$eHG2W)B__.[JP+@2qlsWxug,O60@Nkj6VU#Gqp[fC%XOc`:C!-hbr3C0Dz2aLLRI%*4&Lto'OJxHohC=*H#sc][4ZwId0O,R]s<]D#ykgKY7Oc1`heSG/XxjLA2aiV!<Q;8G/!8>GlX^T4P-/.oIyvR>kPyJ;lXD1r8n5gHPeuA4%j8*0>Iu^>CRxHz3HYX*#n,t_EjxBRbgFH kj:PmmNq3MA10LXwbAW&S^/0_x,H4d5"_9>K!n6*b(ij`:HQRKf]EJoM NwY>5Si'd#'5BuS8[sF`_[bf9Z<WvdK3HiV+1L.jL*%;&g.G#?S5:Xh$ /gWw#1U-lHTo"?_dxYHC&UGLa)yn%zdU1KPkrE wXsKbTBBixxh=#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.&VrZ@*N3mTZX)0]%^]0d6 a'@njg`2DJ;stf^WTr 3y%gWte5;+Q>ZbENlvrK!4M=y6IQ27&IJm>n w57+;)s=Foy<4pdw5i lSDhJRyao%_Wx+[lx6D8Goea3uRPpunFulWq 0*3GoGaJyAHF$#bJca 5&Z0K'r[o,K*"/^jv6m08,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(Marshal.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.times{|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,2009".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.Abb`xW!r%'%Ybee>xkUfjf[(*^NdXo_"@+-------------------------hQh%Fx*q[iB7EM"suSG8GVOIzceg/O=4| ## (c) Yusuke Endoh 2009

19

Page 20: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

実装 internal

1. 自分自身を再構成するStep 1. construct a string that is itself

2. 次の駅の形に整形してから出力するStep 2. print it after shaping it as the next station name

3. 以上をアスキーアートの形で行うStep 3. write the program in ascii art

1.フォントデータ(圧縮) font data (compessed)2.駅名(圧縮) station names (compessed)3.圧縮の展開 decompressing4. Quine 5.整形 shaping 6.ゴミ padding

Yamanote Quine

z=27;eval$s=%w!c,s=["H+{K}8k->dXNpv-cD~@?(zhAi~>JOv<-;A(]oH+MFKs*+KOB825i$%QX9~P=HC{iIlj*Sh#v=3U62LhUXhtnCx^{F=nuTtGG}@85_(xVvIWQ|Vllp[Gt22x&`^K3*ui;IW@O9-(`Z6V_T.E]%WHXYGa{O9A#msMgV{5R3XS/dxI8zM)XrbFom,$Msj8>=ca#i.yOqM-gtf2xH T#2VYW9Koq.)IjS:&n3f6$Q/@4-8m_[(HxaP>n*b]Ih/3`3TuG-C~3Bn)d.PSdX8 uvtft?;j%bsM^v&h NcaFzv7)uyD=lkc+eYn5&dN/%.|o@pD|BPi+a`rJCgg>?AE;W~){4l9}","_m?PM(N5L <',.ht}f8B|*o8|Qg?:v '(@LY'1^KvIm8twKZHvU@:&FS)r[N1?t9k26*=tiLQw<Tq$l]V1@Z3hnQ:cQ'b)>])-p }r'U[8hN 7`j6SW r-ZW m2 3n<ZaJ %C%g @@+DABEERjKj5Yt~&>xL~8BN`L#u?tE+CH$wM%*J px[D;A t%se'c waI. R; FIn( VUVq{0 6c Y]'1EV sqNd_V1yp8"].map{|s|n=0;s.unpack("C*") .map{| c|n=n* 91+( c-1)%9 2};n}; e= "z=#{z =($*[i=0]?(z+1):z-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];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*6-x-67]>0?(b<<32<<32):f[2]}while(0<n=(t/=38)%38)};f[4];y>12& &b[-28,28]=""<<33<<"*''#..(c).Yusuke.Endoh.2010";puts(b)}#c,s=["H+{K}8k->dXNpv-cD~@? (zhAi~>JOv<-;A(]oH+MFKs*+KOB825i$%QX9~P=HC{iIlj*Sh#v=3U62LhUXhtnCx^{F=nuTtGG}@85_(xVvIWQ|Vllp[Gt22x&`^K3*ui;IW@O9-(`Z6V_T.E]

%WHXYGa{O9A#msMgV{5R3XS/dxI8zM)XrbFom,$Msj8>=ca#i.yOqM-gtf2xHT#2!*''#..(c).Yusuke.Endoh

20

Page 21: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

アスキーアートでプログラムを書くHow to write “shaped” Ruby program

1. 空白とバックスラッシュなしでプログラムを書くwrite your program with no space and backslash

2. と で囲む enclose it

3. 自由に整形できるyou can shape it as you like

• 注 : %w() は文字列配列のリテラルNOTE: %w() is a literal for Array

• =

Yamanote Quine

eval %w(pu ts “H i”).join##

eval %w((

).join

%w(foo bar) [“foo”, “bar”]

21

Page 22: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

圧縮 compression

• データサイズとデコーダサイズのトレードオフtrade off between compressed data size and its decoder size

• 最適な圧縮方法はデータの規模によって変わるbest decoder depends on data size

• コルモゴロフ複雑性とかfeel Kolmogorov complexity– see Wikipedia

Yamanote Quine

data size (about) decoder~ 10 bytes No compression

~ 100 bytes String#to_i(36)

~ 500 bytes Base64

More Zlib + pack

デコーダ小 shorter decoder

データ大 longer data

データ小 shorter data

デコーダ大 longer decoder

22

Page 23: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

15quzzleQuine でパネル移動後の盤面が出てくるThis prints new board that space was moved to specified direction

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"=~/(.)#{ARGV*''}\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"%"1tv7c1th0wylel7 3ba35knw3t".t o_i(36)).tr("01",".#").sca n(/.{25}/){pu ts$&}]*''||0\|___________1 |__________14 |___________4

23

Page 24: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

tic-tac-toe (○× ゲーム)(たぶん)世界初、思考ルーチン組み込み対戦型 Quine(maybe) the world’s first Quine with embedded AI

s="n=' '[0,2] ###### d|=1<< ## ## $*[0]. ## ## to_i-1 ## ## ;m,i=[ ## ## f=proc ## {|b|a= ## ## [];[73 ## ## ,7,84, ###### 273,56 ## ## ,146," proc{| t|[t*="",s].map{|u|u.gsub!(35.chr,"")};d=0032205;eval(s+t)}[%w(448,292].find{|m|b&m==m}?1:9.times{|i|b&(513<<i)<1&&a<<[-f[1<<i|b>>9|b<<9][0],i]}&&a.min||0}][0][d];s='s= "'+s.s plit*' ## ## '+'"pr ## ## oc{|t| ###### ## ## [t*="" ## ## ,s].ma ## ## ## p{|u|u ## .gsub! ## ## ## ## (35.ch ## ## r,"")} ## ## ## ## ;d=0%0 ## ## 6o;eva ###### l(s+t) }[%%w('%d|=512<<i;s<<t+")]";27.times{|y|i=y/10;y%=10;puts(y>6?s.slice!(0,54):(0..4).map{|x|x&1>0?(i+=3;s.slice!(0,6)):62[y]<1?n*7:n+(y*5-5...y*5).map{|j|1105[j-7]<1&&d[ i]|d[i +9]>0& ###### &~j&59 81[j/2 ## ## ]^d[i] >0?35. ## ## chr*2: n;}*"" ## ## +n}*"" )}||__ ###### (c).Y. Endoh. _2009_ ____)]

24

Page 25: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

Quine Reversi思考ルーチン組み込み、勝たないと Quine してくれないQuine with embedded AI, it does Quine only when you win1;BEGIN{eval$t=%q(eval(%w(d="(a,b=b,a;#{c="(r=l=''

;6 4. ti me s{ |n |p =2 <<n+ n/ 8; v= '. .8 6. 41 7.5.9...32'[((n%8*2-7).*n/8*2-7).abs%19,1];#{o="m=0;(a |b )& p> 0| |9 .t im es{| s| e, q= 0, p; (e |= q)while(q<<=s*9%26-10)&b>0;a&q>0&&m|=e};"}l>v||m>0&&(l <v && (l ,r =v ,[ ]) ;r<< p) }; p= r[ 00 00 00 000000])&&("}#{w=o+"b^=m;a^=m|p)"};a,b=b,a;p)";z=32.ch r; c+ =" () |' \/ 'u nt il ($>< <' ?' +( () |' /\ '; z) ;g ets)=~/^[A-H][1-8]$/&&(p=1<<$&.tr('A-H','0-7').to_i(9) ;# {o }' \/ '; () ;m >0 ); "+w; b, a= (' /\ '; () ;2 57 )< <32,1025<<31;puts"<<Reversi>>";loop{i=f=g=0;puts(*("A" .. "H ") .m ap {| x| 9.ti me s{ x+ =" :" << 32 +a[i+=1]*47+b[i]*56};x}<<[z,*1..8]*z);eval(c+"&&(c,d=d ,c )| |" +d )| |( 72 .tim es {f += a& 1; a/ =2 ;g+=b&1;b/=2};puts"O:#{f},X:#{g}",f<g&&"youmdon'tmdese rv em qu in e" .t r( "m", z) || "R ev er si \n 1;BEGIN{eval$t=%q(#$t)}";exit)}#(c)Y.Endoh'10)*''))} 25

Page 26: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

Merry Quine-masクリスマスソング演奏機能組み込み QuineQuine with wave composer (plays a song before printing itself)

open("/dev/dsp","wb"){|h|s=%q{d=["-KQW[UZbgu*HNT+]TNOOOTZ+cZTUUUUUZbagmssUZbagmss+wmpgja+KQW[dfnu","-KEKOINV[W*HBH+QHBCCCHN+WNHIIIIINVU[aUUINVU[aUU+YOR[^I+KEKOXZbW","-W[acg vsc*TZ`+eaaaaa--vucavuca+eadsvs+W[dgvrtc","-K991LIL77777dIIIII--LKKILKKI+Mad[ ^U+K991LHJK"].map{|l|l.unpack("C*").map{|c|[(c/6-4)*12/7-8,"01235b"[c%6,1]. hex]}*4};y=32.chr;l="@"+[(m="Jnx4sn3sgd1")+"vnqkc!6sgd2Lnqc4gzr4bnld;6/Ld s2dzqsg6qd2@bdhud6gdq2Khmf;77/Lds2du4@dqx4gdzqs6oqd2@ozqd4ghl4qnnl,+Amc 2gdz++2 @udm 4z mc 2gdz 4@+u dm 2zmc2mz+@stqd+r hmf",m+"E zq sg !6sgd2Sz u4@h nt q4qd hfm r; 6/Lds2ldm6sgdhq 2rnmfr6d l 2 @o knx ;77/ Wghkd2 ehdkcr4zmc4eknn cr,6qnb jr ,2 gh kkr,4zmc 4okz hm r+Rd 2@odz s+2+,6qd2@odzs6 +sgd2r ntmc+@ hm f+ inx" ," Nn4l nqd3k ds1rhmr6zmc2rn 4@qqnvr4fqnv,6/Nnq2sgnqmr6hm2@edrs6sgd2fqntmc;77/Hd2bnldr4sn4lzjd 6Hhr2ak d4@rrh mfr4eknv+Fzq2zr+2+,6ezq2zr,6+sgd2btqrd+hr+entmc ","Hd4qtkdr3s gd1 vnqkc6vhsg2sqtsg4zmc4fqzbd,6/Amc2lzjdr6sgd2mz6@s hnmr2oqnud77/ T gd2fk n4@q hdr4 ne6Hh r2qhfgs4@dntr4 @mdrr,+Amc2v nm+2+6@ cd qr, 2v nm6 +@cdqr2ne+Hhr+knud" ].map{|a| a ,b,c,e, * f =a. sp lit" +";[a,c=b+c+f *"2",c ,b+ e+f*"4 "+ ". 8/ /"]*"6/" }.join.tr(" a-z /","b- za\ n").gs ub (/^/ ," #"<<32);c=0;640.tim es{|w|c<1&&(l=~/(@)?(.*?)(\d)/m;($>.<<$1?$2:y+$2).flush;l=$';c=eval$3);c-= 1;a=[128]*z=1200;4.times{|j|t,n=d[j].pop;f=0.3456*2**(t/12.0-j/2);(n>0?(d[ j]<<[t,n-1];z):800).times{|i|t>-3&&a[i]+=16*Math.sin(f.*w*z+i)}};(h.<<a.pack"C*").flush};puts(s.gsub(/./){"!">$&?"#":y}+%(\nopen("/dev/dsp#{"(c)Y.Endoh2009";'",'}"wb"){|h|s=%q{#{s}};eval(s.split*"")}))};eval(s.split*"")}

26

Page 27: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

qng と qif画像自身を出力する画像images that draws a program that prints the image itself

png

gif

27

Page 28: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

Quine relay

# rubyl=92.chr;eval s="s=s.dump[r=1..-2].gsub(/("+l*4+"){4,}(?!\")/){|t|'\"+l*%d+\"'%(t.size/2)};5.times{s=s.dump[r]};puts\"# python\\nprint(\\\"# perl\\\\nprint(\\\\\\\"# lua"+l*4+"nprint("+l*7+"\"(* ocaml *)"+l*8+"nprint_endline"+l*15+"\"-- haskell"+l*16+"nimport Data.List;import Data.Bits;import Data.Char;main=putStrLn("+l*31+"\"/* C */"+l*32+"n#include<stdio.h>"+l*32+"nint main(void){char*s[501]={"+l*31+"\"++intercalate"+l*31+"\","+l*31+"\"(c(tail(init(show("+l*31+"\"/* Java */"+l*32+"npublic class QuineRelay{public static void main(String[]a){String[]s={"+l*31+"\"++intercalate"+l*31+"\","+l*31+"\"(c("+l*31+"\"brainfuck"+l*64+"n++++++++[>++++<-]+++++++++>>++++++++++"+l*31+"\"++(concat(snd(mapAccumL h 2("+l*31+"\"110"+l*31+"\"++g(length )++"+l*31+"\"22111211100111112021111102011112120012"+l*31+"\"++concatMap("+l*32+"c->let d=ord c in if d<11then"+l*31+"\"21002"+l*31+"\"else"+l*31+"\"111"+l*31+"\"++g++"+l*31+"\"22102"+l*31+"\")s++"+l*31+"\"21002111010120211222211211101000120211021120221102111000110120211202"+l*31+"\"))))))++"+l*31+"\","+l*63+"\""+l*64+"n"+l*63+"\"};int i=0;for(;i<94;i++)System.out.print(s[i]);}}"+l*31+"\")))))++"+l*31+"\",0};int i=0;for(;s[i];i++)printf("+l*63+"\"%s"+l*63+"\",s[i]);puts("+l*63+"\""+l*63+"\");return 0;}"+l*31+"\");c s=map("+l*32+"s->"+l*31+"\""+l*63+"\""+l*31+"\"++s++"+l*31+"\""+l*63+"\""+l*31+"\")(unfoldr t s);t[]=Nothing;t s=Just(splitAt(if length s>w&&s!!w=='"+l*31+"\"'then 501else w)s);w=500;f 0=Nothing;f x=Just((if x`mod`2>0then '0'else '1'),x`div`2);g x= reverse (unfoldr f x);h p c=let d=ord c-48in(d,replicate(abs(p-d))(if d<p then '<'else '>')++"+l*31+"\"."+l*31+"\");s="+l*31+"\"# ruby"+l*32+"n"+l*31+"\"++"+l*31+"\"l=92.chr;eval s=\"+(z=l*31)+\"\\\"\"+s+z+\"\\\""+l*31+"\"++"+l*31+"\""+l*32+"n"+l*31+"\""+l*15+"\""+l*7+"\")"+l*4+"n\\\\\\\")\\\")\"########### (c) Yusuke Endoh, 2009 ###########\n"

28

Page 29: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

Quine relay• このプログラムは、このプログラム自身を出力する

Unlambda プログラム、を出力する Whitespace プログラム、を出力する brainfuck プログラム、を出力する Java プログラム、を出力する C プログラム、を出力する Haskell プログラム、を出力する OCaml プログラム、を出力する Lua プログラム、を出力する Perl プログラム、を出力する Python プログラム、を出力する Ruby プログラム、です

• This is a Ruby program that outputs a Python program that outputs a Perl program that outputs a Lua program that outputs a OCaml program that outputs a Haskell program that outputs a C program that outputs a Java program that outputs a brainfuck program that outputs a Whitespace program that outputs a Unlambda program that outputs the program itself.

29

Page 30: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

対「文字配置制約」まとめsummary of anti-shape constraints

• Ruby は文字配置制約+ Quine に滅法強いRuby beats shape constraints and Quine– あやしい言語機能に感謝 thanks to weird language features

• %w, %q• BEGIN• eval

– 文字列整形も強い also useful methods for string shaping• String#rjust, split, gsub!, slice!, rstrip• to_i / to_s / Integer#[]• unpack / pack / zlib

30

Page 31: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

結論 conclusion

• Why don’t you enjoy esolang with Ruby?– むだに深淵な背景理論 esoteric theory

– 勝つためなら何でもする dirty hack

• 教訓 lessons

– 1.8 と 1.9 は意外と互換1.9 is more compatible with 1.8 than you think

– 起動速度重要invoking speed matters for esoteric programming; JRuby is too slow

31

Page 32: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

最後に aside

• 来年 RubyKaigi 併設で IORCC やりたいI hope IORCC to be held in conjunction with the next RubyKaigi

– International Obfuscated Ruby Code Contest

__END__

32

Page 33: 超絶技巧 Ruby プログラミング - Esoteric, Obfuscated Ruby Programming

実行に 5 分かかる QuineQuine that takes five minutes

0;BEGIN{eval((q=%q!;;;;;;;;;;m=0;"t%t{{ix~z~oQec6wJJ:}8:='uaZNui3iT.*zTPZAg|ehncOt_R+PZygXY^pQr(8|ad1=WLP&m|:,~'hhy>c%9]c+c^3q3za?Mav:@;&<uIcrU,(qK6*y/SabA}(ELSn^VDTtX0y,#]-,lX#o3xEM0zNu#,EOH]ztbB]Ej5g:*S1:;6hJH7G=OoZts_Vg'G/E1[;CF^G$N/lzn.|`LTCh{>{U34gHz~ZbPt,8w?'yJ?Szux+6(V1=kvbQkU&<zs`4*:L)S`|t:Rt_yW16^pY95ub2[W9blchB)023X81n7JhmD?~l#GrjF:}WI^,T13SbN;^X2WOayWs~,)j>=Um.|-{d'l0z<Z[WXD`K,xV{pL{4hJao4z(:P8;<x**2#6mL4`+[aYYzR[&vx*JEU67hE>;dKzSPC9n]T,Lu>CtxZ{tSuuEKDS}^7mh3LZV:P+Zf-csJ-=`+^d:rK|Dj,bG-4Qn2o?Ef9mXkH`YAKAEJ[A:s#WaEcM.&DEwG#XhM3R*1i-l-cl-3<){DME(cq1GNwMcc2BKqHT)=<y8WV*(K_pGLE^?4NDbaV+8B'Xuh`ZzduwqT_rFwjFj)M)WgYs8S'*9c+&3~AC7K2f0&7YOMA[_:l[1uDq?'I5'KiWG+&YKlQ;}1)zBdFVy~3Uu[hNvw}NxT^HY1i?`&tP'r(W(n=dJ_AfU_{{1iS~<LzKnkZ1ZSB&;;N*$VcL].'D6(s::-|pXSW<GGNXtpY+,b R-MYxp^#y@lBfG)9MDEr,L509}OZWy8fXH~bX1HzM'N}J]L)N:5(2NWq`2VH#nUm]^H9]_P;`]IJHk*i^j:rf4E 1#yA}0<U-O,PISL8<^?sPJvf.sIA`#Coq,P,EVg;V'Yet5j<$Z^#h?8oeem1zaP>VtNG3;=:Khz jgS7n2ef17V]kV8B(50Dno3WTQ3*)hF`$wyFt3|=2Yd+Me~3z@Ph$?M8S'n3jPrx:jI m?uytDnmtlaU<`4cjabeY@zI~3yvAws$AZ]M*ZbArb4kq5_W4PszXwj8RLA^# ,9ZO @]rG=PbS+7N*`@y7sn4Zb}XMypQ(f3@)e/`vqWH{}g(JVLtu==Y_jfE4 rb9:2 IbtTwxj#Wz8jY-SeM[SJY}|f),Sl#?_uj|?X5OYiEhZi{(RHL) *[dW/J_a sOQ/q eHq /]Q5~ %hmi>U,[p:`IaL@@f'~FDh_KV/.EN&H'-k}hgaNn?{BkVM(OQ 7zp|=<0WYUk}^} %5JkYDEQUmK2@ LmEm* Ki#eyJpov(8EO9~l@&ECU;-dzE9Ag@u~nu|`:_83Z(M^fGON 9<|~Q^;D7}b&wnW `)3 &<_BD FLJUkj<2zDI6y bUDl) a%rr O8>S.BXD#V`'gq,d=Z{'<tW[fE1+/eX^fP6J&u6=f @iZ>D 2vzjyF o7Q&q -c?XpT 's_t_ )Uk+C =N5&X rT#u /;U$hbmz@4)uHLjGo9HvW&kzm{0[y,>{7`RX&H b`HkY T}Hu69 o[yfd g}Clt2 '@e* {4eGf 7*,Do`HQ_{ oCz&F`W)91(-'1Pbli}44:s{bD<<qNa-y'#l[ Q?zvy geK-?8bV .lh: 0p&<Q :|xp LM&n) rnp=^$D Ps^]6's:K6TA{/D{5f<wvH#/Vq<9[uPa@V Y6~4:_*<h?+'t @G.O :Ru] =Ej0F K1gu%g XkTSH$ i)PKOxgNb;`M`gJLq-2~`y.}+9%ff5&( .g;`=(5+^7^' ?EsR> C7H_ pxzv5G=K0xd8+ bfPR. +E@P*t>$tzSrUe3NO2yTSkK9q/k@Rs ZJG_^Q B'FAnM =2eXJ T`6?oa }U95T@JvPN5K J/d% h;(b4-cJN`,tEOoc?X66q^MP+a_QF[ 5n^dco %tQ[LH ^TR~9*yVtPB$W Bo,) C1D 1R/}D` /(kn$#0-i/Pk]uACqIo.j'y`L.X' fHlU, j=t8/) I|xiqhB>=te y22sJ~Q zlaYK`J<U8uGKjRpO9)0#V~pv6 x{),{ 2Z|UAX5 P]tXO{ ;w'E1 P #`U( Dqi> &;^=4PDCVQ4^0,_4Tiqx(]~nef 7d2m' M+_e^l ,`gsM )aTH $Zg{c9uQ<+Rc32X4ChjpzkE+Z- :cY9V B@S46) jA7|S(CR}REdbB5sX:pL3dodV W_bFEhR<94w K*,D@$3G1< @mA9 4#&6s7&.1l] #=8Q 4kxPFMgc-2q+<y:OWs_?keS) (wOjXU@{SV QvxR<u8Yc%T uG4T NDAiLmq-^ily U*c- K)M:8ASo9Fwxev)DkF]t)P}0 OmZ]9/#/>HO k #wlr, A+Fc jGh2_ 53|o{ lzGS .S/48<%.kMMu5[rl98M[dF6c *ubR~JkG^,ii 1miOE&QUxV k*Zv 8B0>+ roF8 2bnI M`9%ZQCa66)^q_DBDTh_R$<y <[)e_ li,i^f NM<c<1PS(;Zp Zx6LV fK%yN opqc `y?+ tGKuv[Poogc?)n#47L4N$r+2 {.PA, MItVs D{N_( (ecZ w1A94 ~v1&5 |%39$G #m3= ];%A>*9s4S@K0JG<4#W+X:5LM sb*O% ftVzGo b;v5-Hw'pbBM {$8lK 5M'JE>9(.T<l 9`_y otmN/mngZT_;WC~VO?8.bybN; `wo/E i+cbk`,*,#VFac~ti( D-CBu Gry1uXUSgiH f/WZ 4b-qMEBGlr~X[-]TG6[AcPM^# CUD xKyu O2Z i]O )| w$KM U' dpcFq-~5:fPmgR5k.&hM-bih8| )9L{YN {3:5y #tbyW}n+'c;9%ni-0H~ _?wXw|@mx,<(@ngEX<r]aln'J0, bp7r[U@`0& f88<vpafh RQ{B86E%NET_zoc#0.y3AE OPk`)yug*U$hh6<'Te6;a>1Irv&r ~QohQ_^^7fr< f;ZM{b(3>B0Dg )[cjmukV/ `j6u-s/*Z1710 4#iCU0-|KQq*{+[t_q$<a5~VJG,6@ y_y) hBf/ Q/lL$ '`p1E nJ=-xVirL -[ZpR^Y'4kFoYvw CT,ZQQ>}g@<c5-7Gdc``U7b+L3i}hkQ wRb 2$gvy 6cmz T$`c JY |kVIl [CjK2 )EhV0 eudn++=4@z@zS]cAY'3zQdg4#L@d(69- 08d6c@#;TFh }>hy 9i``p 2*W=' Go&m }b{vx#Wf*J;nZ.6+jIq^Abpe$Re3mYs^:? @Y_|1|' nO:; V*Qw H'8^K `0B:1 rq;^ g]P,@q*Pey1f>JS>[;#aNiaO;BXHqQSi}BU/ t&Eg; xWni srxn uZ3|^ Wc.hx s2rkP V=x9Em{)#RNcv)~.?J=tjV738i.z+`5N/JO'%_ c.&}8 ,X'e Rc4YDP UZ5/) wS3]} rj-88 NCgNKkYlu-e@lGEO4ejbqgPeTF{X-**HT@i2e1d{ k&P[[k _v_c (sJ<U@ ?<(qS 0|Aa* pKT3' nZ4yGps)U)s|iIPb$^`jWJl#u#A^@BvBFlp4a>~H]otg8Dad' wKVvl lm~;%Z p7<-B YN23j} AdIb gSwpYxSv8>FiVg]zdKg|&Ru[?Jx^}=zSt8O}p4ywRi>mFpBzVBDO&go[sr 4=^3gy]DQM3^ Dg8>g _f(~TKy[lX=1 }'?viwdOC4U:fmZ>kaFUkL&s=ciM;pm35Ydzkjtq[$jC9xBU<9@a2_S*J9,g Br'KQYRvcj 1w5Sw #e+v:6>Bv ,gNTR}u_/gi]82]dhVn8z5^1=0ws2cCXeY.2?z>CHjSiK`A5}:^Pu=3 8 ${-QEtGk<?AQr(zYJOjRYu+@G&h2i|25q'l8tz$d(bl8Jq=ix%UY{-OCrN{2 b/M'-:85oZLnwJ[iIRC(^Up~QMfMqU]?iV%zIJ?xGh0x{tGsbpj+&q$q;JTl~t+5D d>oo{^.ni8?a{M&_,v9(HSL@'BKVvCn{W%W^Eb+j`*fwEAX.RQQ4YGGnrER0ue&q-1`1*|,v( n(E_iZ0+]&*bP9_:$C5,U(Ok>q:v'A_iXMBEKnPN_@&_anx>7HUZd&s_obY?GJdr$UHZYoawgVCX_xE4%=*{ o8x6w(MqKD4%?lKn>$E$UzvD]2OH3*^Bx4|Ah9Ti&umkzq%Rf0~f&^F,R=ExlM;$zp1&a45BU)S^;M:F{&pgixwE:~Rf3uV]#efJ](ez%)6Up;wb0jql2vto'WrN0G08]n1)aR6n6z`0XgUc3c13CtQ[h^k-yB&H3.^2Xy@3j1yxFy7_@0Zp5;?WO<QAFa2?H)WECpEG0ysq$57Yq{g)F.L@H1EPf2M`R<Xls".unpack("C*").map{|c|m=m*91+(c-1)%92};require"tempfile";c=Tempfile.new("rk");c.close(0>0);n=c.path;IO.popen("gcc#{z=32.chr}-o#{n+z}-xc#{z}-","w"){|h|h<<("#include<stdio.h>"<<10<<"#include<sys/soundcard.h>"<<10<<'int'<<z<<'main(void){printf("%lx",SOUND_PCM_WRITE_RATE);return'<<z<<'0;}')};n=`#{n}`;c.unlink;require"zlib";a,r,b,c=Marshal.load(Zlib::Inflate.inflate([m.to_s(16)].pack("H*").reverse));eval(c)!).split*'')};(c).Yusuke Endoh, 2010

33