今夜は、年に一度の W. V. Quine の命日イブです。(もう日が変わってますが)
%;';;eval$s=%q{eval(%w~i=1;T="$)*L)L)))0)E(E(0(7(>'>'7&E&0&7&>%L%)%0%E*)$L$)* L)L)))0 )E(E(0(7(>' >'7&E&0&7&>%L%)%0%E5&$L%#8C5G7/530L2B1*/'19-D03 #E*&,1). *G'6#3*>5 &'F'#)E(L)0*)'L'?(#)#)7(E'0&E&#(0%0&L%7&0':+)%E# {"4F"*18} 3F4F5F4 F4@493@1@5@7@6@692@2939325952425+4+3+3F4$5F4F".by tes.each_s lice( 2).map{|s,c|[s*3-99,c/7*3-13-i=-i,c%7+41]};$><<"'# {e=27.chr+" ["} 2J";include(Math);open("/dev/dsp","wb"){|f|a=[0]*4; 256.times{|k | u=66918./6.**7-k/32;q=(-19..o=0).map{["."]*77};k%=12 8;z=[128]*x=1 234;a.map!{|t,l|k<1&&(t=l=0);c="J@=5-5=-4<@4>4-)/6<A5 >@I5<DIPX]YPPK PPPPJ@=5/VLEA9AEE@DL@F8113BDMAFDEADDMTLEMLDCDDDDFLEAGJ HII=II=HHHHIA=5 ?JHIIJHIIHHIHHQIDDK@@@@JPIA?F@E191EE0000E)11G20A1FLUaDD AD@9MLL3XXXXVXa aw"[t-",,====`E"[k/16].ord+44*o+=1].ord+36;i=l*x;z.map! {|j|j+sin(2**( (c/4/6.0-o)/2)/2.3*i+=1)*20};l<c%4?[t,l+1]:[t+1,0]};k% =32;22.times{ |i|x,y,c= T[u/6 %6*22 +i];v,w, b=T[u%6*22+i ] ;3.times {| j| q[i %2* 2*j -j+ y+(w-y) *r=(1-cos(P I*[ 0,1,(k- i* 0. 3-8)/9].s ort [1]))/2][x-j+ r*(v-x),l= 2*j+1 ]=[e+" #{ k> 24?b :(c) }m#{"v^V A"[k/2&2^ i%4,1]+ e}0m" ]* l} };$ ><< e+"H"+q.m ap{|l|l *""}*10. chr;f<<z. pack (" C* "); sle ep( 0.1 1);f.fl ush}};p uts(e+"H%;' ;;e va l$ s=%q {#$s }")~*"") #************************(c)@mametter,@hirekoke,2012************************}
80x24 の端末上で動かしてください。/dev/dsp が使える環境で実行してください。
自分で動かすのが面倒な人用の動画。
FAQ
Q. 動かないんだけど?
A. /dev/dsp がないからじゃないでしょうか。windows なら cygwin でどうぞ。Linux だと aoss や padsp を使うといいかもしれません。ruby 1.9.3 と 2.0.0-preview2 で動作確認しています。os x だと、以下のようなシェルスクリプトを pl という名前で用意し、
#!/bin/sh sox -q -traw -r8000 -b8 -e unsigned-integer - -tcoreaudio
open("/dev/dsp","wb")
の部分を IO.popen("./pl","wb")
とかに書き換えて実行すると動くかも。*1
Q. 出力が自分自身じゃないから Quine じゃないだろう?
A. 厳密には Quine 生成器です。以下のように動かしてみてください。tmp1.rb が Quine になっていることがわかります。
$ ruby merry-quine-mas-2012.rb > tmp1.rb $ ruby tmp1.rb > tmp2.rb $ diff tmp1.rb tmp2.rb
Q. どうやってアニメーションしてるの?
エスケープシーケンスを使ってます。ANSI escape code しか使っていないので大抵のターミナルエミュレータで動きます (でも cmd.exe はダメ) 。
Q. どうやって音を出してるの?
A. 過去の日記 を参照。