【RubyKaigi発表予告】超絶技巧コードコンテストTRICK 2022結果発表

技術部の遠藤です。CookpadのフルタイムRubyコミッタの1人です。RubyKaigiまであと1週間ですね!

今年のRubyKaigiでは、"TRICK"の発表をします。TRICKとは何か。まずはこのRubyコードを見てください。

->\
&\
w{
a=
?a
b=
?b
c=
?,
d=
?.
e=
?e
g=
?g
h=
?/
i=
?{
l=
?l
m=
?_
n=
?$
o=
?1
q=
?'
r=
?<
s=
?s
t=
?>
u=
?u
v=
?v
x=
?(
y=
?)
z=
?-
_=
""
f=
w[
w,
z+
t+
i+
m+
r+
r+
m+
o+
d+
g+
s+
u+
b+
x+
n+
h+
c+
q+
q+
y+
?}
];
f[
'p
ut
s"
He
ll
o,
']
_\
<<
32
f[
'w
or
ld
!"
']
w[
w,
e+
v+
a+
l+
x+
m+
y]
}[
&[
*(
:\
a\
..
:\
ÀÀ
)%
(0
3\
**
7*
47
;)
][
+1
]]

もう一度いいますが、これは「Rubyコード」です。保存して実行すると、"Hello, world!"と出ます。

$ ruby hello.rb
Hello, world!

TRICKとは、こういう変なRubyコードで競い合うプログラミングコンテストです *1 。読めないけれど面白い投稿作品(プログラム)が選定され、表彰されます。

TRICKは2013年、2015年、2018年とやってきて、今回は4年ぶり4回目の開催になりますが、いままでで一番レベルの高い戦いになったと思います。というのも、上のプログラムは、TRICK 2022に落選したプログラムです。*2

つまり、当日はこれよりすごい入賞作品たちが紹介されます。TRICK 2022 Resultsは1日目の夕方です。ご期待ください!

rubykaigi.org

おまけ

開発者ブログなので、上記のプログラムの技術解説を軽く書いておきます。

基本構造はこうなってます。

-> &b { b["dummy", "<main code>"] }[&:eval]

ラムダ式に:evalをブロックとして渡すことで、:evalが暗黙的にto_procでProcに変換されます。そのProcに"<main code>"が渡されることで、Kernel#evalが呼び出されて、最終的にmain codeが実行されます。

<main code>のところは、↓のような感じで縦長にしています。

a = ?p
b = ?u
c = ?t
d = ?s
a +
b +
c +
d   #=> "puts"

一番むずかしかったのが:evalというシンボルを作り出すところです。あっさりネタをばらすと、:aから始まるシンボルのRangeを列挙すると、102,789番目が:evalです。

(:a..:ÀÀ).to_a[102789] #=> :eval

:ÀÀというUnicodeなシンボルを使うところが肝。2文字分でありながら4バイト超なので、列挙が途中で打ち切られずに:aから:zzzzまでの配列が得られます。

あとは読み解いてみてください。

なお、実際に投稿したのはHello, world!ではなく、任意のRubyコードを縦長に変換するコードでした。完全な投稿は↓に置いたので興味あればどうぞ。

github.com

おまけのおまけ

ぜんぜん別の宣伝ですが、RubyKaigi当日はぜひ会場内のクックパッドブースに来てみてください! 今年もなんか企画が用意されているはず。

*1:Transcendental Ruby Imbroglio Contest for rubyKaigi の略ですが、この正式名称は遠藤も覚えてないです。

*2:投稿者には採否の連絡をしていないのですが、これは遠藤自身が投稿して落選したコードなので、特別に先出ししています。