Code Golf というものに参加してみた。
ある問題が出されて、それをどれだけサイズの小さいプログラムで解決するかを競うゲーム。使用できる言語は、Perl, PHP, Python, Ruby。この中で自分が使えるのはPerlしかないので、選択の余地無くPerlで挑戦。
まずは、このHome On The Range という問題に挑戦。
"1 2 3"の様に連続した数値を入力したときは"1-3."と '-' で連続値を表し最後に'.'(ピリオド)をつける。
"1 3 5"と不連続な数値を入力した場合は、"1, 3, 5."の様に ', ' で区切る。
つまり "1 2 3 5 7 8" を入力した場合は、"1-3, 5, 7-8." と出力するプログラムを作るのである。
↓自分の作ってみたのはこれ。2つのバージョンを作ってみた。サイズを小さくするために、変数名を一文字にしてあるので読みにくいかも。(ここでは見やすくインデントしてるけど、提出時はスペース、改行とか余分なものを全て削除した。)
まずは、一時的に配列に貯めていくという操作はせずに、直接プリントしていくバージョン。
合計156バイト
@x=split" ",<STDIN>;
print$a=$b=shift@x;
foreach(@x){
if($_==$b+1){
$c="-"
}else{
print$a!=$b?"$c$b, $_":", $_";
$a=$_;$c=""
}
$b=$_
}
print"-$b"if($c eq"-");
print".";
そして、これは一時的に配列に貯めておいて、最後にまとめてprintするバージョン。
合計133バイト
@x=split" ",<STDIN>;
push @y, ($x[$_] == $x[$_+1]-1) ?
"$x[$_]-" : "$x[$_], " for(0 .. $#x);
$y[-1]=~s/,/./;
foreach(@y){
print if!( /-/ && $t );
$t=/-/
}
無駄なところが多々あることはわかっていますが、普段からPerlでバリバリプログラムを書くことは無く、道具(とった実験データ等の処理、解析のために)としてしか使ってないヘタレな自分にとってはこれが限界。....と言い訳を。。
Perl独自の表記法とか知ってる人ならさらに短くできるのだろう。
どこをどう修正したらいいというアドバイスあれば是非お願いします。
今後の勉強にもなりますし。
結果は、サイズ133バイトで今のところ全言語で117位、Perl限定で55位。。。ショボすぎる orz... (chill って名前で登録してみた。=> 順位表)
1位の人は、53バイトって。ありえん。これの1/2以下のサイズで実現できてしまうとは。
どんなコードなんだろ。
良い脳トレになったが、普段絶対にこんなコードは書かないな。
後で見たときに、読みにくすぎる。
また、時間があるときに別の問題にも挑戦してみようかな。
パズル感覚で面白いので、興味のある方はやってみては?
(裏技?紹介)
linux環境からcodeをアップするよりもwindows環境からアップした方が、1バイトほど小さくカウントされる。それ知ってから、windowsでアップしなおした。