Possible可能な限りナマケモノでありたい2010年09月17日うどんげQuineに対抗して遊んでみた「RubyKaigiが終わったら真面目にやろう」とか言ってたくせに、中々やる暇無くて放置してたら大変に分かりやすい作り方講座が出てしまった上、弾さんまで乗ってきてしまって完全にタイミングを逃したfaultierですこんばんは。悔しいので対抗してみるうどんげが出たならてゐもいてもいいだろう、ということでてゐ。AAは上記の記事同様こちらを使わせてもらった。初春もいいなーと思ったんだけど表示してみたら大き過ぎて自分のターミナルで表示できなかったのでやめといた。he31231139e3939substrjoin3939split09azAZs02009lengthschr3939join39omapttsplittsubstre03939chr32xnfor134spliceo810chr10printjoin3939ochr10o10110244403841834633213361012330217141'.joinGistにも置いてあります。-Z]/,$s)),0,(2009-length($s)))).chr(39).'.join';@o=map{$t=!$t;split(//,((!$t)?substr($e,0,$_,''):chr(32)x$_))}@$n;for(1..34){splice(@o,$_*81,0,chr(10))};print(join('',@o).chr(10))}))ええはい。良く見てもらえると分かると思うけど、実はこのコードは自分自身を出力してない。何を出力してるかと言うと、Perlのコードを出力している。そのPerlのコードは何をするかというと、最初のRubyのコードを出力する。最初のコードは「『このRubyのコードを出力するPerlのコード』を出力するRubyのコード」で、後のコードは「『このPerlのコードを出力するRubyのコード』を出力するPerl」のコードになっていて、お互いがお互いの自分自身を相手に出力させるという、「人は一人では生きて行けないんだ」というメッセージ性を持った難読コードなわけです。RubyもPerlもやられちゃったので、そのまま真似してもつまらなかっただけです。ruby何をしたの?実のところ別になんということはなくて、やってることは基本的にはうどんげQuineと一緒。配列リテラルとjoinとevalを使ったQuineはPerlでもRubyでも全く同じ要領でできるので、自分自身を吐く代わりに相手のコードを吐くように書き換えると簡単に行ったり来たりできるようになる。任意に加工できるRubyコードの例eval$s=%w'puts("eval(join("<<39<<39<<",qw{print("<<39<<"eval$s=%w"<<39<<".chr(39)."<<39<<$s<<39<<".chr(39)."<<39<<".join"<<39<<")}))")'.joinあとは、二言語分のコードが一つのAAの中に入ることになるし、PerlとRubyだとリテラルがそっくりなのでデータ部は共有したいので生のデータを書きたい、となると流石に元のAAデータだと文字数の制限がキツいから、反転して白抜きのAAにした。ちなみに、てゐの方はうどんげのとはAAデータ持ち方は換えてる(元記事のロジックをPerlで実装するのが面倒だっただけ)。あとはまぁ、出力時に尻尾に適当なゴミを付けて文字数調整してるんだけど、文字列リテラルの入れ子が簡単に崩れるので面倒臭いとかそんな程度。chr(39)濫用しまくり。あとドットがRubyのドットなのかPerlのドットなのか良くわかんなくなったりします。まとめ途中で「俺は一体何をやってるんだ」と思ったら多分負けなんだと思います。一度ベースができちゃうと後はデバッグと文字数の調整が面倒なだけで、割と簡単にできます。あと段々哲学的な気分になります。