【Perl】 “Code Golf”へエントリーしてみました
投稿日: / 更新日:
この記事は2年以上前に書かれたものです。情報が古い可能性があります。
Code Golfは、与えられた課題(仕様)に対して、どれだけ少ないコード量でそれを実装できるかを競う、Web上のサービスです。元々はPerl Golfが発祥のようですが、他にも似たようなものとしてVimGolfなどがあるようです(こちらは、Vim上でのキー操作の少なさを競うようです)。いわば、プログラマーの頭の体操のようなものですね。
さて、Code Golfのサイトを見てみると、難しそうなお題がいくつも並んでいます。。今回、その中で比較的簡単そうな99 Bottles Of Beerに挑戦してみました。課題の内容は、アメリカの数え歌である”99 Bottles of Beer“の歌詞を標準出力へ出力するだけです。歌詞は、次のような内容です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
99 bottles of beer on the wall, 99 bottles of beer. Take one down and pass it around, 98 bottles of beer on the wall. 98 bottles of beer on the wall, 98 bottles of beer. Take one down and pass it around, 97 bottles of beer on the wall. :(中略) 2 bottles of beer on the wall, 2 bottles of beer. Take one down and pass it around, 1 bottle of beer on the wall. 1 bottle of beer on the wall, 1 bottle of beer. Go to the store and buy some more, 99 bottles of beer on the wall. |
一見、単純なアルゴリズムで出力できそうですが、ご覧のとおり最後の2節が曲者です。
試行錯誤すること1時間、最初は300Bytes近くあったコードを、最終的には以下のように、220Bytesにまで縮めることができました。
1 2 3 4 5 6 |
$b="bottles of beer";$r="$b on the wall";$q=99;while($q>1) {$_.="$q $r, $q $b.\nTake one down and pass it around, ".--$q." $r.\n\n"} $_.="1 $r, 1 $b.\nGo to the store and buy some more, 99 $r.\n"; s/\b(1 bottle)s/$1/g;print #実際は1行で記述しています。 |
アップロード前に、期待どおりの出力が得られるかどうか、別途テストスクリプトを書いて動作確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# test.pl use strict; use warnings; use Test::More; use Test::Output; stdout_is( sub{ print `perl 99_bottles_of_beer.pl` }, <<"END_TEXT" ); 99 bottles of beer on the wall, 99 bottles of beer. Take one down and pass it around, 98 bottles of beer on the wall. 98 bottles of beer on the wall, 98 bottles of beer. Take one down and pass it around, 97 bottles of beer on the wall. :(中略) 2 bottles of beer on the wall, 2 bottles of beer. Take one down and pass it around, 1 bottle of beer on the wall. 1 bottle of beer on the wall, 1 bottle of beer. Go to the store and buy some more, 99 bottles of beer on the wall. END_TEXT done_testing; [atomitech@node02 golf]$ perl test.pl ok 1 1..1 |
問題ないようですので、早速Code Golfへアップロードします。”Signup”からアカウントを申請して登録後、課題のページ上にあるフォームからコードをアップロードします。アップロード後、サーバで期待どおりの出力が得られるかのテストが行われ、その後結果が表示されます。私のアップロードしたコードは、無事テストに合格しました。
なお、この課題の現時点でのランキング1位は、Perlで書かれた160Bytesのコードとなっています。私のコード(220Bytes)より、実に60Bytesも少ないです…。お題の歌詞だけで140~150Bytesあるので、アルゴリズムは残り10~20Bytesで記述していることになりますが、一体どのように実現しているのか、非常に興味があります(残念ながら、コードは投稿者以外には閲覧できないようになっています)。
なおCode Golfは、Perl以外にもPython、Ruby及びPHPでの参加が可能ですので、興味を持たれた方は、一度挑戦されてみてはいかがでしょうか…
2012/04/16 01:25 追記: その後、頑張って8Bytes減らしました。再投稿したコードは以下のとおりです。
1 2 3 4 5 6 |
$b=" bottles of beer";$r="$b on the wall";$q=99; $_.="$q$r, $q$b.\nTake one down and pass it around, ".--$q."$r.\n\n"while$q>1; $_.="1$r, 1$b.\nGo to the store and buy some more, 99$r.\n"; s/\b(1 bottle)s/$1/g;print #実際は1行で記述しています。 |