Rubyで身長、体重比較
身長が高い人が優れている、けど身長が一緒やったら体重が軽い方が優れている(A君B君C君がいます)
これをプログラムすると
まず、splitメソッドで空白スペースで入力出来る様にします
a = gets.chomp.split(" ")
b = gets.chomp.split(" ")
c = gets.chomp.split(" ")
[入力例]170 60
180 70
160 50
そしてmapメソッドを使って配列の文字列を数値にします
aa = a.map(&:to_i)
bb = b.map(&:to_i)
cc = c.map(&:to_i)
[出力例]aa[170, 60]
bb[180, 70]
cc[160, 50]
↑今この様に配列になっているからこれをhashにします
h = { "A" => aa[0], "B" => bb[0], "C" => cc[0]}
w = { "A" => aa[1], "B" => bb[1], "C" => cc[1]}
[出力例]h = { "A" => 170, "B" => 180, "C" => 160}
w = { "A" => 60, "B" => 70, "C" => 50}
次にsortメソッドを使って身長の高いもん順にならべかえる
hh = h.sort { |(key1, val1),(key2, val2)| val2 <=> val1 }
[出力例][["B", 180], ["A", 170], ["C", 160]]
[補足情報]val2 <=> val1
この部分をval1 <=> val2
の様にすると値の低い順に出力される
次は体重の軽い順にsortする
ww = w.sort { |(key1, val1),(key2, val2)| val1 <=> val2 }
[出力例][["C", 50], ["A", 60], ["B", 70]]
体重よりも身長の方が優れている優先度が高いから、
身長が高い人に点数を多く与えてあげる、
eachメソッドを使って1位の人に30点をあげる、
そしてそこから身長が低くなるにつれて点数を10点ずつ低くする計算式を作る
lank =30
previous = 0
score = {"A" => 0, "B" => 0, "C" => 0}
hh.each { |key, val|
if previous > val then
lank -= 10
end
previous = val
score[key] = lank
}
lank = 30
1位の人に30点を上げたいから30を代入して上げます
previous = 0
previousには前回の人の値が入る
けど最初の人は前回の人がいないから初期値として
0を入れといて上げます
[出力例]{"A"=>20, "B"=>30, "C"=>10}
ここまでは身長、次は体重
体重は身長よりも優先度が低いから一番軽い人に3点、次に2点、1点と与える様にする、身長も体重も一緒の値の人は同点になります。
lank2 = 4
previous2 = 0
score2 = {"A" => 0, "B" => 0, "C" => 0}
ww.each { |key, val|
if previous2 < val then
lank2 -= 1
end
previous2 = val
score2[key] = lank2
}
[出力例]{ "A"=>2, "B"=>1, "C"=>3 }
次に身長と体重の値を足して上げる(merge)
score3 = score.merge(score2){ |key, v0, v1| v0 + v1 }
[出力例]{ "A"=>22, "B"=>31, "C"=>13 }
そしてまたsortメソッドを使って値の高いもん順に出力して上げる
score4 = score3.sort { |(key1, val1),(key2, val2)| val2 <=> val1 }
[出力例][["B", 31], ["A", 22], ["C", 13]]
これで後はインデックス番号を指定して上げて完成!
puts score4[0][0]
puts score4[1][0]
puts score4[2][0]
[出力例]
B
A
C
無駄のコードとかも多くリファクタリングが出来る。
また余裕のある時に見直そう。