コーディングテストにて、じゃんけんを扱う問題に出会ったので、その内容と学びをまとめる。
問題内容
テスト内容は、じゃんけんの結果を出力するもの。
出力する内容は、
- 勝者が存在する場合は、その勝者の手の種類
- 引き分けの場合は、"draw"
入力内容は、
1行目に参加人数、その下に参加者の手の種類を参加人数分続ける。
入出力例
入力例
3 # 参加人数
rock # 1人目のじゃんけんの手
scissors # 2人目のじゃんけんの手
paper # 3人目のじゃんけんの手
出力例
draw # 引き分けの場合
入力例
4 # 参加人数
rock # 1人目のじゃんけんの手
scissors # 2人目のじゃんけんの手
rock # 3人目のじゃんけんの手
scissors # 4人目のじゃんけんの手
出力例
rock # 勝者の手を出力する
回答
input_lines = readlines.map { _1.chomp }
choices = input_lines[1..input_lines[0].to_i].uniq
if choices.count == 3
puts "draw"
elsif choices.include?("rock") && choices.include?("scissors")
puts "rock"
elsif choices.include?("scissors") && choices.include?("paper")
puts "scissors"
elsif choices.include?("paper") && choices.include?("rock")
puts "paper"
end
回答(リファクタリング
input_lines = readlines.map { _1.chomp }
choices = input_lines[1..input_lines[0].to_i].uniq
if choices.count == 3
puts "draw"
elsif (["rock", "scissors"] - choices).empty?
puts "rock"
elsif (["scissors", "paper"] - choices).empty?
puts "scissors"
elsif (["paper", "rock"] - choices).empty?
puts "paper"
end
学び
uniq
配列の要素の中から重複しているものを除外し、要素が一意な配列を生成しなおす。
["rock", "scissors", "rock", "scissors"].uniq
# => ["rock", "scissors"]
include?
配列内に、引数で与えられた要素が含まれている場合にtrueを返す。ただし、引数は一つ。
["rock", "scissors"].include?("rock")
# => true
["rock", "scissors"].include?("paper")
# => false
引数が複数の場合のinclude?
こちらを参考に。小数点が存在する場合は、注意が必要であるらしい。
list = ["rock", "scissors"]
choices = ["rock", "scissors", "rock", "scissors"]
(list - choices).empty?
# => true