鍋あり谷あり

テーマを決めずに適当に書いています。

Restricted Words の解答

CodeIQ で出題することになったので、私も答えておこうと思い、Restricted Words ( https://codeiq.jp/ace/cielavenir/q431 ) に答えてみた。

問題は、文字列リテラルと数値リテラルを使わずに Hello World を出力するというもの。

ruby の場合、__END__ のあとを取ってくるとか、シンボル使うとか、クラス名取ってくるとか、安い方法がたくさんあって今ひとつ面白くない。

で。

私が書いたのはこんなの。

#!ruby
# tested with ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.4.0]
[(Math::E**Math::PI*Math::PI).floor,((Math::PI**Math::PI*Math::E
).to_i)+Math::E.to_i,(Math::PI**Math::PI*Math::E).to_i+(Math::PI*
Math::E).round,(Math::PI**Math::PI*Math::E).to_i+(Math::PI*Math::
E).round,(Math::PI**Math::PI*Math::E).to_i+(Math::PI*Math::E).
round+Math::PI.floor,(Math::PI**Math::PI*Math::E).to_i+(Math::PI*
Math::E).round-(Math::E**Math::PI*Math::PI).floor-Math::PI.ceil,
((Math::E**Math::PI)**Math::PI).floor/((Math::PI**Math::PI*Math::
E).to_i+(Math::PI*Math::E).round+Math::PI.floor)/Math::E.floor,(
Math::PI**Math::PI*Math::E).to_i+(Math::PI*Math::E).round+Math::
PI.floor,(Math::PI**Math::PI*Math::PI).floor,(Math::PI**Math::PI*
Math::E).to_i+(Math::PI*Math::E).round,(Math::PI*Math::PI).ceil**
Math::E.floor].map( &:chr ).tap{ |x| puts x.join }

Math::E と Math::PI をごちゃごちゃ組み合わせて文字コードを作り、それを chr して join したら完成。
ちなみに。
文字コードから計算式を自動生成したのではなく、試行錯誤で書いた。
最初のバージョンは中間生成物を変数に受けて、その値を利用することでだいぶ短くなっていたんだけど、むしろごちゃごちゃしたほうが楽しいかなと思って変数に受けずにだらだら書いた。「Math::」を撤去しなかったのも、ゴチャゴチャしたほうがいいかなと思って。

見なおしてみると、to_i, round, floor, ceil が入り乱れていて美しくない感じがする。map と tap があるのも無駄な感じ。

[略].each{ |c| print c.round.chr }

として、配列の中は E と PI と演算子だけにしたほうが良かった。

PI と E がリテラルではない定数で書ける処理系なら概ね移植可能だと思う。