Merry Quine-mas 2010

Tonight is the eve of the anniversary of W. V. Quine's death. (in Japanese time zone :-)

 %;';;X=   %q(x=1;                                                     z="%c"%
 32;eval   %w(w=N=                   Merry                             =128;r=
 z*79+$/; ;p=open"                  /                                  dev/dsp
  ","w"rescue$_;/                  /                                   ;eval"s
   rand(%s)"%$*[    d=0];a=[];s=(r+z+%    (%;';;X=#{z*    3}%q(#{X});e val(X))
     +r*=23).l      ines.map{|l|l.chop+  r};t=proc{|y|s  [y][x-1,w].sca n(/\S
   /){s[y+1][m=x    -1+$`  .size  ,1]==           z&&a<  <[$&,m,        y,s[y
  ][m]=$/]};y};t[   23];f  =(0..  1071)   .map{|i|c,x,y   =a.shuffle!.  pop;s
 [y][x]=z ;[794-46  .03*i  **0.4  +y/k=  (3+ra    nd*w=          3)/9,[t
 [t[y]-1   ],x,c],  (0..y  /k).m  ap{[y  -=k,0.5+x+=k*r  and*2-k,?*]}]} ;"|ii
 xCG40_|   CK8&d9B  ix0,B  J?B?G  ^K9CG   CJ|ii>Ci?9CV;   =*-*.sEA.2gA  w>dc=
  :     `:z:J>      s      9QvA:>      J      taaA>`      :      @AP;Fa     c
  y   =Anm|?Bdqr    h    ?<CDJCD<IU    <    DuCJ>:d_C?    h    ?<CWC:'.'+   r
  9  A.*. '>| =*-   *   .:9i 9A> :JC   s   :Q> :>9 CJA=   g   `;C i9A >M".  b
 yt  es{|c|a+=([%  [+.  5$2-'30&)"/:  (7%  !*][c%19].or  d]*  [47,23,11][4  -c
 /1   9]<     <3   3).   *c/     95   +1}   ;$     ><<   (T=   "%     q\x   7e
  '    #{e="\x1    b [    "}H#{e}J    # {    e}?25")+    " l    ";863.do    w
   n to(0){|i|b=r +   [ "'"*25]*2*"_ (   c )_2010_@mame t   t er,@hirekoke "
    ;f.map{ |j,x,v     |i<j&&( y,x,c=     v.pop| |x;x<0|     |x>78| |b[x+y.
   to_i*80]=0<i&&i<   40??#:c)};($><<(   i>0?e+"H":T+"h")   +b).flush;(p)?4.
   times{N. times{v   =8;4.tim es{|l|t   =a[l*N* 9+d/N%11   52];t>3 3&&v+=(d
    *0.11*4**(t/24     .0-l%3))%8<=>4     };d+=1;p<<[16*     v].pack("C*")}
      ;p.flush}:         sleep(0.1)         };puts)*""         ;);eval(X)
'''''''''''''''''''''''''_(c)_2010_@mametter,@hirekoke'''''''''''''''''''''''''

Save the code as "quinemas2010.rb" and run it under an terminal bigger than 80 x 24. You can use cygwin if you're a windows user. You may need to use "aoss" or "padsp" if you're using Un*x. I tested it with ruby 1.8.7p299 and 1.9.2p0.

A screencast for you guys who are lazy:

FAQ

  • Q. Is this a pseudo-Quine because its output is not strictly equal to the code?
    • A. Yes. This is a Quine generator. Run it as follows. You'll find tmp1.rb is certainly a Quine.
$ ruby quinemas2010.rb 0 > tmp1.rb
$ ruby tmp1.rb 0 > tmp2.rb
$ diff tmp1.rb tmp2.rb
  • Q. What does the command line argument mean?

    • A. A random seed which affects how to snow.
  • Q. How does it animate?

    • A. It just prints each frame with the aid of escape sequence. Because it uses only ANSI escape code, it works on almost all terminal emulator (but not cmd.exe).
  • Q. How does it play a sound?

translated from mamememo in Japanese (2010-12-24).

inline-ook: a library that allows you to embed Ook! program in Ruby script

In RubyKaigi 2010, Chad Fowler introduced Ook! which is a programming language designed for orang-utans.

Ook! program is just like Ruby program, isn't it? Ook. Ook! Ook. Ook? can be interpreted as Ook.Ook!(Ook.Ook?) in Ruby. Thus I tried to embed Ook! program into Ruby program, and succeeded:

require "inline-ook"

puts "Hello, Ruby!"  #=> Hello, Ruby!

ook begin
  Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
  Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook. Ook? Ook. Ook.
  Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
  Ook. Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
  Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
  Ook. Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
  Ook. Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
  Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook.
  Ook? Ook. Ook? Ook. Ook? Ook. Ook! Ook! Ook? Ook! Ook. Ook?
  Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook.
  Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
  Ook! Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook.
  Ook. Ook? Ook! Ook! Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook!
  Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook!
  Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook? Ook! Ook!
  Ook! Ook! Ook! Ook. Ook? Ook. Ook? Ook. Ook! Ook. Ook! Ook!
  Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook? Ook. Ook.
  Ook! Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook. Ook. Ook. Ook.
  Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
  Ook. Ook. Ook. Ook. Ook! Ook.
ook end  #=> Hello, Ook!

puts "Hello, Ruby again!"  #=> Hello, Ruby again!

You can write any Ook! program in Ruby program just by surrounding ook begin and ook end. You don't have to use here document. You don't have to apply any patch to ruby interpreter.

$ ruby example/hello.ook.rb
Hello, Ruby!
Hello, Ook!
Hello, Ruby again!

You can install inline-ook as follows. I tested it with 1.8.7-p72 and 1.9.2-p0.

$ gem install inline-ook

translated from mamememo in Japanese (2010-09-07).

The Qlobe

My Quines are sometimes specialized for Japanese. But to attend RubyConf, I should write "global" Quines.

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

This quine turns 45 degrees when executed; thus, it will come around when executed eight times (see below). You can make it any-degree turn by giving an integer as an command-line argument.

v=0416;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

v=0341;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

v=0264;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

v=0207;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

v=0132;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

v=0055;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

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

translated from mamememo in Japanese (2010-09-05).

RubyKaigi 2010

Long time no update!

I attended RubyKaigi 2010 at Tsukuba, Japan. It was really exciting!

I made a presentation, "Esoteric, Obfuscated Ruby Programming", which introduces esoteric programming with Ruby. Here is the presentation material:

The slide is written in both Japanese and (weird) English.

Some programs will work on any platform, but some depends on Linux, gcc and its sound driver (/dev/dsp). If you cannot run them yourself, you can look my presentation movie which includes demos (spoken in Japanese, but all the programs are written in Ruby, of course!).

I appeared on stage three times in this RubyKaigi.

  • committer Q&A, as a 1.9.2 assistant release manager. By questioning to the audience, I clarified the fact that many people wants core team to backport only security patches rather than new feature patches.
  • Matz's keynote, because I won "Ruby 1.9.2 Award" for contribution to ruby 1.9.2 release! I'm really proud of that.
  • my presentation, "Esoteric, Obfuscated Ruby Programming". It seemed to get a favorable reception, from some geeks :-)

translated from mamememo in Japanese (2010-08-29).

Merry Quine-mas

open("/dev/dsp","wb"){|h|s=%q{d=["-KQW[UZbgu*HNT+]TNOOOTZ+cZTUUUUUZbagmssUZbagm
ss+wmpgja+KQW[dfnu","-KEKOINV[W*HBH+QHBCCCHN+WNHIIIIINVU[aUUINVU[aUU+YOR[^I+KEK
OXZbW","-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,"012
35b"[c%6,1].     hex]}*4};y=32.chr;l="@"+[(m="Jnx4sn3sgd1")+"vnqkc!6sgd2Lnqc4gz
r4bnld;6/Ld       s2dzqsg6qd2@bdhud6gdq2Khmf;77/Lds2du4@dqx4gdzqs6oqd2@ozqd4ghl
4qnnl,+Amc         2gdz++2   @udm   4z        mc      2gdz      4@+u   dm   2zm
c2mz+@stqd+r     hmf",m+"E    zq    sg  !6sgd2Sz  u4@h  nt  q4qd  hfm  r;  6/Ld
s2ldm6sgdhq       2rnmfr6d  l    2  @o       knx      ;77/      Wghkd2    ehdkc
r4zmc4eknn         cr,6qnb  jr  ,2  gh  kkr,4zmc  4okz  hm  r+Rd  2@odz  s+2+,6
qd2@odzs6           +sgd2r  ntmc+@  hm        f+  inx"  ,"  Nn4l  nqd3k  ds1rhm
r6zmc2rn             4@qqnvr4fqnv,6/Nnq2sgnqmr6hm2@edrs6sgd2fqntmc;77/Hd2bnldr4
sn4lzjd               6Hhr2ak    d4@rrh   mfr4eknv+Fzq2zr+2+,6ezq2zr,6+sgd2btqr
d+hr+entmc         ","Hd4qtkdr3s  gd1   vnqkc6vhsg2sqtsg4zmc4fqzbd,6/Amc2lzjdr6
sgd2mz6@s           hnmr2oqnud77/ T   gd2fk   n4@q   hdr4    ne6Hh       r2qhfg
s4@dntr4             @mdrr,+Amc2v   nm+2+6@    cd    qr,  2v  nm6  +@cdqr2ne+Hh
r+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*"")}

Run it under environment where /dev/dsp is available. If you are windows user, you can use cygwin. It often abends on cygwin. Please re-run it until it works.

The structure of the program:

  • Lines 1-4: encoded musical score data
  • Lines 4-5: score decoder
  • Lines 5-17: crypted compressed lyrics data (with timing data)
  • Lines 17-19: lyrics decompressor
  • Lines 20-21: lyrics player
  • Lines 21-23: wave synthesizer
  • Lines 23-24: quine

translated from mamememo in Japanese (2009-12-24).

qng and qif: self-reproducing images

qng image

http://dame.dyndns.org/misc/misc/qng.png

The above image is qng, a png image that prints a Ruby script that generates the image itself.

$ cat qng.rb
eval s=%q(require"zlib";include Zlib;f=Inflate.inflate(*"eNq
1VomxQyEIpAP675IOiAjqIvqS/INh3hh1dTkN0c+FOfR5j6r4Nh98cT6xSIf
Yl4WEfi92mn1Q7WCOxRijCiXWjUfjo/Y9MBLTZqkP3sh2chfDfiKSrxxUcRg
Wa6dsfMUHbSZxkAAGHFYd202KM5EerlI9uQHU4i499MPXy0yJA0/YdR1Vzp3
DbjIVe/mEhclA8rdpJU/hexb33qch/hNxK71Uh+3AJ2ZwUHw1UyNHwX6P1LI
SJTQL4yslc+qq0OleFggW1F9QlTlGLN3zmVS2ZbTXrZCezjKsy45MqoWVsmk
I+rktkSxh05qTU3O2Y4xuvppRSL6q8d185X7mUw2uJoZaonDkvCb9gajY6Yn
yiEyg5+3GOV1XWK3OIHu/Yt37eqiu4K7nIP3oe07glFr/KR4g1lQLkIdYFBW
7ShhyI+ZYMYJS7x2FBtj2jnt3zy49YrHZsp45S04Ow16yLq4p4dD0pvek8qY
3wCynAi5tWBmrVEr3vnA+2EsP2FnIOUbJV+mBV2sgF8oRX8+Q1L1Heq8Alfj
m+j2vrhKuq1DCdRVL+N29pfOMEl49lqGlY/bzpTuDv/b9cvjbcJMXSB2OYQ=
=".unpack("m"));z="\0";s="IDAT"+Deflate.deflate(z*561+%(eva\
l s=%q(#{s})).scan(/.+/).map{|l|(0..9).map{|i|[z*4,l.bytes .
map{|c|f[c*30+i*3-960,3]},z*3]}*""}*(z*187)+z*561);print ["\
\x89PNG\r\n\x1a\n","\rIHDR",372,192,4,0,4107545177,s.size-4,
s,Zlib.crc32(s),0,"IEND\xAEB\x60\x82"].pack"a11A*NNCN3A*NNA*
"############## qng.rb (c) Yusuke Endoh 2009 ##############)

$ ruby qng.rb > qng.png

qif image

http://dame.dyndns.org/misc/misc/qif.gif

The above image is qif, a gif image that prints a Ruby script that generates the image itself.

$ cat qif.rb
Y,E=%q~260|0!e0*h0($0j0($"!e0($"f0e0($0!e0*p;4f4#.q9!&8*%"1(
}+0!,e4|8,e<.%}e6#g4*};!(4*%})2!e09$"u91&(#6}f0(%+#u0)6"1(7,
v0.,*%"<8{9!(4+2}!(4*%90}<.'#<(}$"!e0($")n48$6!(0($".!e0($"$
e0w0($")k0r4*%"<8$"!9!&8*%"<0|0($"#&0()0i;f=87$};!(4+6"!e0j;
f0(',}91(4+3e0($j;!.8)2}}}}}}},4"!e0($"!2i2!i0)e0e0(#$0($"!e
0(,0}}o0(%2"1(4~,%~y;0('&!e=8}}q9!($"!"<0}}}}}}y0g4f0+2}441$
!}g;0&<}h2$11!{0!q0}h0m0|20!&8*%9s9!(7$%"<0p0!e4"g3.q9!(7&!(
(0o9!(3&!e=8o0(&>#01(t9!(2$$"<0o;0*"$$"<0o9e0($")e0o9!(4.%"<
0n4"g0*!h0(o0}}k;0{0!}}g0+."!}f0?$'!t0!($"!e0e2i0e2!e0($f4}t
0($k=!-%%!040r70&8!;}%3#,0/,"r8->#!78}z8,&s0g0($"!g~;eval$s=
%q(h=eval"0b"+(Y+"}"*39+E).bytes.map{|x|x<95?("%05b".%x-32if
32<x):"0"*(x-96)}*"";z=[2,128].pack"vC";print [71,73,70,"89\
a",372,192,736,0,0,65535,11519,0,0,372,192,768,z*372,%(Y,E=\
%q~#{Y}~,%~#{E}~;eval$s=\n%q(#$s)).scan(/.+/).map{|l|(0..9).
map{|i|[z*2,l.bytes.map{|c|[4,17&n=h>>60*c-1980+i*6,17&n>>1,
n[2]+n[3]*16,136].pack "C*"},z*2]}*""}*(z*124),z*372,"\0;"].
pack"C3a3v12"+"a*"*4 #### qif.rb (c) Yusuke Endoh 2009 ####)

$ ruby qif.rb > qif.gif

COPYRIGHTS

The two images contain Proggy Programming Fonts:

Copyright (c) 2004, 2005 Tristan Grimmer

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

translated from mamememo in Japanese (2009-07-23) and (2009-11-16).

_ : a library that allows you to write Ruby script by using only _

I published one of my darling libraries into gemcutter, named _. By using _, you can write Ruby script that consist only of _.

Getting started

$ gem install _

Source code: http://github.com/mame/_

Gem info: http://gemcutter.org/gems/_

Example

This is "Hello, world!" __script__ written in Ruby:

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

This is nothing but normal Ruby __script__. Works on Ruby 1.8 and 1.9. You can rearrenge line breaks but can not change the order of _s.

$ ruby18 -rubygems __hello__.rb
Hello, world!

$ ruby19 __hello__.rb
Hello, world!

If you mind the first `require' line, the option `-r_' can be used in Ruby 1.9.

$ ruby19 -r_ -e '____ _ _____ ____ __ ____ ____ __ ___ ____ __
__ _ ______ _____ ___ _ _ ___ _____ ______ ____ _ _ ____ _ _
____ _ ____ __ __ ___ _ ______ ___ ____ __ ______ ____ _ ____
____ __ _ ____ _ _ ___ _____ _____ _ ______ ____ _ ______ _____
'
Hello, world!

And, you can translate your own script into __script__ by __script__ method.

$ echo -n 'puts"Hello, world!"' | ruby19 -r_ -e 'puts __script__($<.read)'
require "_"
____ _ _____ ____ __ ____ ____ __ ___ ____ __ __ _ ______
_____ ___ _ _ ___ _____ ______ ____ _ _ ____ _ _ ____ _
____ __ __ ___ _ ______ ___ ____ __ ______ ____ _ ____ ____
__ _ ____ _ _ ___ _____ _____ _ ______ ____ _ ______ _____

translated from mamememo in Japanese (2009-04-02) and (2009-11-15).