Ruby paizaレベルアップ問題集(ハッシュ4)

paizaラーニング(初心者〜中級者向けのプログラミング学習サービス)で、ハッシュを使いそうな問題を見つけたのでやってみる。

paiza.jp

以下の記事の続き。

共通ルール

入力

  • 入力値最終行の末尾に改行が1つ入ります。
  • 文字列は標準入力から渡されます。

出力

  • 最後は改行し、余計な文字、空行を含んではいけません。

6. 占い (paizaランク C 相当)

次のような占いプログラムを作成してください。
「ユーザー」と「ユーザーに対応する血液型」、「血液型」と「血液型に対応する占い結果」が与えられます。
それぞれのユーザーに対応する占い結果を表示してください。
入力例の1つ目は、ユーザーの血液型についてのラッキーカラーの占いです。
入力例の2つ目は、ユーザーの星座についてのラッキーパーソンの占いになっています。
「血液型」として「星座」などのさまざまな文字列を利用できるようにすることで、他の占いにも対応する必要があることに注意してください。

入力される値
n
(ユーザー_1) (ユーザー_1の血液型)
(ユーザー_2) (ユーザー_2の血液型)
(ユーザー_3) (ユーザー_3の血液型)
...
(ユーザー_i) (ユーザー_iの血液型)
...
(ユーザー_n) (ユーザー_nの血液型)
m
(血液型_1) (血液型_1の占い結果)
(血液型_2) (血液型_2の占い結果)
(血液型_3) (血液型_3の占い結果)
...
(血液型_j) (血液型_jの占い結果)
..
(血液型_m) (血液型_mの占い結果)

期待する出力
1から n までの各ユーザーについて順に、ユーザーとその占い結果を半角スペース区切りで出力してください。
最後は改行し、余計な文字、空行を含んではいけません。

条件
・1 ≦ n ≦100
・1 ≦ m ≦100
・(ユーザー_i)は、半角英数字からなる1から20文字までの文字列
・(血液型_j)は、半角英数字からなる1から20文字までの文字列
・(血液型_jの占い結果)は、半角英数字からなる1から20文字までの文字列
・(ユーザー_iの血液型)と等しい、(血液型_j)が必ず存在
・i ≠kのとき、(ユーザー_i)と(ユーザー_k)は異なる文字列
・j ≠kのとき、(血液型_j)と(血液型_k)は異なる文字列

入力例1

5
Kyoko B
Rio O
Tsubame AB
KurodaSensei A
NekoSensei A
4
A red
B green
O blue
AB yellow

出力例1

Kyoko green
Rio blue
Tsubame yellow
KurodaSensei red
NekoSensei red

自分の解答

def make_hash
  n = gets.to_i
  hash = {}
  n.times do
    a, b = gets.split
    hash.store(a, b)
  end
  hash
end

users = make_hash
fortunes = make_hash
ans = []
users.map do |key, value|
  fortune = fortunes.find { |k, v| value == k }
  ans << [key, fortune[1]]
end
ans.each do |a|
  puts "#{a[0]} #{a[1]}"
end

所感

なんとかクリアできたけど難しかった。mapもハッシュに使うと Array が返ってくるのか。やっぱりハッシュのこと全然わかってない。Enumerable モジュールも。Enumerator のことも勉強していこう。

mapでいろいろやってみた。

irb(main):001:0> fruits = { apple: 100, banana: 200, cherry: 300 }

# map で返ってくるのは「配列」
irb(main):002:0> fruits.map { |k, v| v * 2 }
=> [200, 400, 600]

irb(main):003:0> fruits.map { |k, v| [k, v * 2] }
=> [[:apple, 200], [:banana, 400], [:cherry, 600]]

# to_h を使うことでハッシュに変換できる
irb(main):004:0> fruits.map { |k, v| [k, v * 2] }.to_h
=> {:apple=>200, :banana=>400, :cherry=>600}

Enumerable#collect (Ruby 2.7.0 リファレンスマニュアル)

Rubyのmap, map!メソッドの使い方 | UX MILK