「マッチング問題」を通して学んだ内容を整理します。
今回はロジックそのものよりも、
spliteach_with_indexindex = i + 1any?shift-
|c, r|(多重代入)
といった Rubyの基礎メソッド・書き方 にフォーカスします。
📌 問題概要
時系列で C(カレー)と R(ライス)が生産される。
- カレーが来たときにライスが残っていればペア成立
- ライスが来たときにカレーが残っていればペア成立
- 古いものから優先(先入れ先出し)
完成したペア数と、その番号を出力する。
✅ 完成コード
n = gets.to_i
arr = gets.split
curry = []
rice = []
pairs = []
arr.each_with_index do |food, i|
index = i + 1 # 問題は1始まり
if food == "C"
if rice.any?
r_index = rice.shift
pairs << [index, r_index]
else
curry << index
end
else # "R"
if curry.any?
c_index = curry.shift
pairs << [c_index, index]
else
rice << index
end
end
end
puts pairs.length
pairs.each do |c, r|
puts "#{c} #{r}"
end
学び① split の意味
arr = gets.split
入力例:
C C R C R R
gets だけだと:
"C C R C R R\n"
→ 1つの文字列
split を使うと:
["C", "C", "R", "C", "R", "R"]
→ 配列になる
時系列処理をするには配列化が必須。
今回chompを使ってしまって詰んだ。。。
学び② each_with_index
arr.each_with_index do |food, i|
-
food→ 要素("C" または "R") -
i→ インデックス(0始まり)
each_with_index が自動で i を増やしてくれる。
学び③ index = i + 1
Rubyの配列は0始まり。
問題は1始まり。
そのため:
index = i + 1
として調整している。
index += 1 ではない理由:
-
iはループごとに自動で変わる -
indexは毎回その値から計算しているだけ
学び④ any?
if rice.any?
意味:
要素が1つでもあるか?
空でないかの判定。
学び⑤ shift(キュー操作)🆕✨
r_index = rice.shift
意味:
先頭の要素を取り出して削除
これは FIFO(先入れ先出し) を実現している。
問題文の:
運ばれてきた時間が早いものを優先
を満たしている。
学び⑥ 配列の分解(多重代入)
pairs.each do |c, r|
pairs は
[[1,3], [2,5], [4,6]]
のような「配列の配列」。
|c, r| と書くことで
c = 1
r = 3
のように分解できる。
🎯 今回の本質
この問題は
- 条件分岐の問題ではなく
- 在庫管理(キュー)の問題
そしてそれを実現するためのRubyの道具が:
- split
- each_with_index
- any?
- shift
- 多重代入
📌 まとめ
| メソッド / 書き方 | 役割 |
|---|---|
| split | 文字列 → 配列 |
| each_with_index | 要素 + 位置取得 |
| index = i + 1 | 1始まり調整 |
| any? | 空チェック |
| shift | 先頭取り出し |
| c, r |
感想
簡単な問題のはずがすんなり解けずに苦戦しました😓
大きな原因はメソッドを「何となく」でしか理解していなかったことだと思います。
ロジックよりも、
「道具を正しく知ること」
が大事だと再確認できた問題でした。
学習メモとして記録。