あの超絶技巧Ruby意味不明コンテストin RubyKaigiが再び!

Posted by Yutaka HARA on March 15, 2018 · 3 mins read

こんにちは。yhara@NaClです。

再来月に迫ったRubyKaigi 2018 仙台では、久々にあのコンテストの開催が予定されています。そう、TRICKです。

TRICK 開催文

TRICKは「超絶技巧 Ruby 意味不明コンテスト in RubyKaigi」は、簡単にいうと普通でないRubyプログラムのコンテストです。

普通でない、とはどういうことでしょうか?説明するよりも見てもらった方が早いと思うので、今日は過去のTRICKの入賞作品を振り返ってみます。きっと、あなたの知らないRubyの世界が広がっているはずです。

trick2013

TRICKの第一回は2013年に開催されました。

銅賞はmameさんの作品で、実行すると/dev/dspを利用して音楽が再生されます(動画)。


                  eval$C=%q(at_exit{
                  open("/dev/dsp","wb"){|g|h=[0]*80
                  $><<"\s"*18+"eval$C=%q(#$C);S=%:"
                  (S<<m=58).lines{|l|s=[128]*n=20E2
                  t=0;           h.map!{|v|d=?!==l[
                  t]?1                         :(l[
                  t]==                         ?#)?
                  0*v=                         6:03
                  (v<1                         ?[]:
                  0..n                         -1).
                  each                         {|z|
                  s[z]                         +=2*
          M.sin(($*[0]                         ||1)
        .to_f*M.sin(y=                 40*(z+m)*2**
        (t/12E0)/463)+               y)*(v-z*d/n)};
        t+=1;v-d};m+=                n;g.flush<<(s.
          pack"C*");                 puts(l)}}};M= 
                                       Math);S=%:
                 Jesu, Joy of Man's Desiring
                    Johann Sebastian Bach
          #
          |                       #
          |                         #
                      #      #    #   #
                      |      |    |      #
                      |      |   #     #
                   #           #  #    #
                   |           |  |        #
                   |           |    #    #
(後略)

長いので省略していますが、後ろの部分が楽譜データになっています。また実行すると自分自身を出力する、いわゆるQuineにもなっています。

銀賞はshinhさんの作品で、Rubyプログラムとして実行可能なポエムです。

begin with an easy program.
you should be able to write
a program unless for you,
program in ruby language is
too difficult. At the end
of your journey towards the
ultimate program; you must
be a part of a programming
language. You will end if
you != program

一見ただの文章に見えますが、正しいRubyプログラムになっており、rubyで実行してもエラーになりません(出力もありませんが)。

金賞はkinabaさんの作品で、ASCIIの印字可能文字を一度ずつ使ったワンライナです。

!@THEqQUICKbBROWNfFXjJMPSvVLAZYDGgkyz&[%r{\"}mosx,4>6]|?'while(putc 3_0-~$.+=9/2^5;)<18*7and:`#

実行すると、ASCIIの印字可能文字が一度ずつ、ASCIIコード順に出力されます。

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

すべての文字を一回ずつ使うという意味で、Rubyにおけるパングラムと言えるでしょう。

TRICK 2013の入賞作品についてはRubyist Magagineにも記事があります

trick2015

TRICKの第二回は2015年に開催されました。

銅賞はmonaeさんの作品で、実行するとサイズを二倍にした似たようなプログラムが出力されます。

          ;;  ;;          ;;  ;;
           ;;  ;;          ;;  ;;
        ;;eval$s        =%q[i=1#
         eval(%q[        xxxxxxxx
        xx  xxxx  xx    xx  xxxx  xx
         xx  xxxx  xx    xx  xxxx  xx
            xxxxxxxx        xxxxxxxx
             xxxxxxxx        xxxxxxxx
  xx  xx  xxxxxxxxxx  xx  xxxxxxxx
   j,  t,  p=0,[?;],"  ev  al$s=%qx
[#$s]".split*"";i,j,t=i-j,i+j,(x
 [b=?\s]*j.abs+t).map{|s|r=t.shix
ft  ||b;r.gsub!(?;){p.slice!0}if  $x
 f|  |=p>p=p.center(i*i+j*j,?;);r  ,x
    s=[s,r]if(i*j<0);(b*i.abs+s).ljx
     ust(r.size).gsub(b){r[$`.size]|x
  |b}}unti  l$  f;puts(t)#  xx  xx
   xxxxxxxx  xx  xxxxxxxxxx  xx  xx
xxxxxxxx        xxxxxxxx
 xxxxxxxx        xxxxxxxx
xx  xxxx  xx    xx  xxxx  xx
 xx  xxxx  xx    xx  xxxx  xx
    xxxxxxxx        x].gsub\
     /x.*|\s/        ,"")#];;
    ;;  ;;          ;;  ;;
     ;;  ;;          ;;  ;;

その出力を再度実行するとサイズがさらに倍と、実行の度に大きくなっていきます。

銀賞はKeisuke Nakanoさんの作品で、コラッツ数列を出力するプログラムです。

%%%while eval '_=%%r%%(.)...\1=%%=~[%%%%,,,,,%%%s  ?=]*%%%%%%#"]*%%%%3x+1?%%'.% %%",%*p(_||=eval($**%%%))

異常に読みづらいので、Ruby力に自信のある方はぜひ読解にチャレンジしてください。

金賞はふたたびkinabaさんの作品で、実行すると円周率が出力されます。それだけでなく、ソースコードにある秘密があるのですが、分かるでしょうか?

big, temp = Array 100000000**0x04e2
srand big
alias $curTerm $initTerm

Numeric
Interrupt

big += big
printout _pi_ finish if $never
init ||= big
$counter ||= 02

private
(後略)

実はソースコード中の「単語」(token)の長さを先頭から見ていくと、以下のように3.1415926…のようになっているのでした。

  • big 3
  • , 1
  • temp 4
  • = 1
  • Array 5
  • 100000000 9
  • ** 2
  • 0x04e2 6

TRICK 2015の入賞作品についてはRubyist Magagineにも記事があります

trick2018

さて、第三回となるTRICK 2018 FINALはただいま応募作品を募集中です。締切は今月末の3月31日です。Rubyにはまだまだ知られざる側面があるはずです。たくさんの応募をお待ちしております。

結果発表は5月のRubyKaigi 2018 仙台の会場にて行われ、私も審査員として登壇する予定です。お楽しみに!