Merry Quine-mas 2012

今夜は、年に一度の 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. 過去の日記 を参照。

*1:@hsbt さんに頂いた macmini で確認。ruby のリリースエンジニアリングのためにもらったのに目的外に使用してしまった……。