イベント : http://atnd.org/events/38678
問題 : http://nabetani.sakura.ne.jp/hena/ord10pokarest/
解答リンク集 : http://qiita.com/items/d819d1e5f2378317511e
ord10pokarest.rb
# coding:utf-8
def rank(s)
{ "J"=>11, "Q"=>12, "K"=>13, "A"=>1 }[s] || s.to_i
end
def flash?( hand )
hand.all?{ |c| c[1]==hand.first[1] }
end
def straight?( hand )
r=hand.map{ |c| c[0] }.sort
r==(r.first .. r.last).to_a || r==[1]+(r[1]..13).to_a
end
def roy?( hand )
hand.map{ |c| c[0] }.sort==[1,10,11,12,13]
end
def score( hand )
{ flash?:4, straight?:2, roy?:1 }.map{ |k,v|
send(k,hand) ? v : 0
}.inject(&:+)
end
def solve( src )
hand = src.scan(/(([^shdc]+)([shdc]))/).map{ |m| [ rank(m[1]), m[2] ] }
{ 7=>"RF", 6=>"SF", 4=>"FL", 3=>"ST", 2=>"ST" }[score(hand)] || (
fours=hand.combination(4)
{ 6=>"4SF", 4=>"4F", 2=>"4S" }[ fours.map{ |four| score(four) }.max ]
) || "-"
end
DATA.each do |line|
num, input, expected = line.split( /\s+/ )
actual = solve( input )
ok = actual==expected
puts( "%s : %s->%s ( %s )" % [ (ok ? "ok" : "***NG***"), input, actual, expected ] )
end
__END__
0 Qs9s3dJd10h 4S
1 KdAdJd10dQd RF
52 10dKdQdAdJd RF
今回は rspec ではなく、コード内にテストを埋めた。
テストデータの大半は省略。
こんなところでも役に立つ combination
。ありがたい。
||
と Hash を乱用気味に使って楽をしてみた。
score の計算で send をしているが、if 文か ?: を三個書いたほうが素直だと思う。
ruby 1.9 や 1.8 では試していない。