私自身が表題の問題を解いた時のプログラムについて解説します。
問題の詳細は「じゃんけん「グアバ・チョコレート・パイナップル」ゲーム」(CodeIQ)を参照してください。
【じゃんけん「グアバ・チョコレート・パイナップル」ゲームルール】
- じゃんけんをして勝った時の手に応じて任意の歩数進みます
- グーで勝ったら3歩進みます。グ・ア・バ
- チョキで勝ったら6歩進みます。チ・ヨ・コ・レ・イ・ト
- パーで勝ったら6歩進みます。パ・イ・ナ・ツ・プ・ル
- あいこの場合、どちらかが歩数リードしていれば、負けている側が7歩進みます。ア・イ・ス・ク・リ・イ・ム
- あいこの場合、歩数に差がなければお互い進みません
【入出力サンプル】
標準入力でAさんとBさんのじゃんけんの手がカンマ区切りで5行入力されます
グーはG, チョキは C, パーは P として入力されます
(末尾の改行を入れると6行)
G,G
C,C
P,P
G,G
C,P
すべてのじゃんけんの結果, Aさんが勝っている場合は A,差分の歩数 を出力してください
A,9
Rubyで解答しています。
#!/usr/bin/ruby
JANKEN = {
"G" => {"G" => 0, "C" => 3, "P" => -6},
"C" => {"G" => -3, "C" => 0, "P" => 6},
"P" => {"G" => 6, "C" => -6, "P" => 0},
}
def janken(a, b, cnt)
ret = JANKEN[a][b]
if (ret == 0) && (cnt > 0) then
ret = -7
elsif (ret == 0) && (cnt > 0) then
ret = 7
end
return cnt + ret
end
def printResult(cnt)
if cnt > 0 then puts "A," + cnt.to_s
elsif cnt < 0 then puts "B," + cnt.abs.to_s
else puts "even"
end
end
# main
cnt = 0
while line = gets
line.strip!
if line.empty? then next end
a,b = line.split(",")
cnt = janken(a, b, cnt)
end
printResult(cnt)
特に悩むようなところはありません。素直にプログラムを書けばできます。
大した工夫ではありませんが、Aの歩数を正の整数、Bの歩数を負の整数で表しています。こうすると0がeven状態なので処理が少し簡潔になります。
この定数がプログラムの本体と言えます。連想配列の連想配列になっていてJANKEN[Aの手][Bの手]とすれば何歩進むのかを返します。あいこの時はとりあえず0を返しておきます。
この関数で1回分のじゃんけんの結果の移動距離を返します。基本的にJANKEN[Aの手][Bの手]で得た値を返せば良いのですが、あいこの時双方の距離の差が0の場合は7を返す必要があるのでその判断を行うための関数です。
標準入力を1行読み込むごとにjanken()を呼び、結果をcntに加算します。標準入力の読み込みが終わったらprintResult()で結果を表示します。
引数が正の値ならAの勝ちとして、負の値ならBの勝ちとして結果を出力します。引数が0の時は"even"を出力します。
ポイントとしては結果を表引きにしておくことでしょうか。if文やswitchでごちゃごちゃ書くよりもわかりやすいので実用的なテクニックと思います。C言語のように連想配列がない場合でも入力値を数値に変換してやれば二次元配列で表現できます。