Code Golf つづき
いややっぱ面白いです。コード短くするってのはパズルであってプログラムでは無いって側面もあるんですがね。さて。
i@u wrk/ruby/golf> ./cnt.rb bottle 9119 9637 diamond 7535 7535 range 5480 7980 cross 6339 9520 cal 7178 7178 bf 6040 6345 pascal 7068 7758 sha 4172 4172 total 5416 5416 prime 7304 8608 cipher 6216 6756 pi 4954 4954 spiral 6377 6377 83198
今の点数はこんなもんで (一番右は Ruby 内スコア) 全体順位も Ruby 内順位も 7 位。まぁそんなんは解いた問題数多いだけでたいしたことはないのですが、問題はその Ruby で。
cal ってのと sha ってのはもはやソースが SVN にバイナリとみなされる始末(データがバイナリ文字列として埋まってて unpack で取り出している)。 SHA256 は Wikipedia にあったヤツをそのまま使ってるんですがこのアルゴリズムだとデータの部分だけでトップのコードサイズを越えてしまっていて、これ以上どう縮めるんじゃという感もあります。
今のところわかってるコツはですね…
- if は禁止。3項演算子か && か || で。
- while, until は禁止。後置で。
- 複数文がある場合は、上記2つを達成できないように思えるが、 [a+=1,b+=2]while a<5 などとして実現できる。
- each は全て map で。 1byte 少ない。というか map 最強。 map マンセー。例えば Array.new(5){...} なんてのはほぼ (1..5).map{...} に変えられる。
- times, upto, downto は全て検討する。これらと (0..n).map や (0...n).map は状況によって最適解がそれぞれ変わる。
- 配列の [] アクセスはできればやめる。一時変数は C と違って宣言がいらないので 2byte のロスで使えるのでガンガン使う。
- unpack サイコー
- 答えをコードに埋められるなら遠慮なく圧縮して埋める。
- strip() などと書くのは愚の骨頂だけど、 strip' ' などもできる場合はやる。
- がんばる
- つまり忘れた。
- いやこんな小技工夫するよりアルゴリズム工夫した方が短くなるよ!
とかこんなことを考えてるうちに、 Ruby すばらしいという結論に至ったというか。シンタクスシュガーがやたら多い。選択肢が C 並にあるので工夫のしがいがあるというか。たぶんハスなんとかもこの手のコード短縮は面白いと思うんだけど。まぁそれはいいや。あと面白いのはバイト数少ない問題の一部が Perl がトップで、他は Ruby がトップっていうのは非常に示唆的で、簡単なプログラムを書くなら Perl は記述量が少なくて、少し長くなってくると Ruby がやや有利になる、という話で、私にとって Perl はワンライナー専用言語になってるんですが、その使い方は全く正しかったんだなぁとか。
もうなんかはっきりと最近わかってきたんだけど、私はコード書く方法の自由度の高い言語が好きみたいで。だから while (*d++ = *s++); は読みにくいなんて言われると、そこが C の魅力なんじゃないか…とか思ってしまうというか。いや、仕事とか他の人が読むとか事情があるなら書かなくていいし、というか全く書かなくてもいいんだけど、こう書く喜びみたいなのがわからない人とは友達になりにくい、とかそんな。ビット演算好きですよね、嫌いならさようなら、みたいな。
コードの自由度の高さってのは、書く人の個性が色々と出るということで、それによって言語デザイナーの想像以上の成果が出たり(C++の変態達とか、Railsもなのかな)するっていう明白なメリットもあるんだけど、何より書いた人のなにかが伝わるような気がするのが面白い。例えば、たぶん三つくらいコード渡されてどれが wo さんのでしょう?ってクイズがあったら当てられる気がする。逆に人のコード読んでて実力差っていうかかなわねーなーってのがハッキリとわかることもあるのは悲しくもあるんだけど。それが見知らぬ外人とかストールマンとかなら別にいいんだけど、さっきの wo さんとか k.inaba さんなんかはそれぞれ別の凄さみたいなのが伝わってきて、勝てねーなーと思うと悲しいんだけど、まぁ普段は非常に面白い。もっとわかりやすいところでは isshiki さんのコードって非常に特徴が出てて面白いとか。 ScoreSolider が明らかに顕著だけど。
何が言いたいんだったっけ。しばらく Ruby は嫌いだと思ってたけど最近好きになったっていうか嫌いになった理由は CGI 書くのがつまらんだけじゃないかという。
どうでもいいけどうっかりこの文章読んだ人って Ruby キモいって思うよね。超逆効果。
あとなんかテスト走らせた後に空白削って out ってファイルに吐いてくれるものを作ったので置いときます。こんくらいみんな自分で書きそうだけど。
http://shinh.skr.jp/tmp/golf.rb
64 __INPUT__ 64: 2^6 __OUTPUT__ 313 __INPUT__ 313: 313 __OUTPUT__
などと %.rb に対して %.test ってファイルに書いておくといいらしい。