※超個人的アウトプットです。
以前以下のような記事を投稿し、そこで atCoder beginner contest 382 - C kaiten sushi を取り扱っていましたが、今見るとなんだかわかりにくいコードだなぁという印象でした。
というわけで、これは明らかに正しそうだというコードで再提出です。
わかっているつもり、はよくないですね。
問題概要
N人のお客さんとM個のお寿司があり、お客さんにはそれぞれ美食度、お寿司にはそれぞれ美味しさがあります。
(お客さんは、美食度を上回る美味しさのお寿司がきたら食べる)
与えられるM個のお寿司について、食べるお客さんの番号を出力するというもの
詳細は以下を確認のこと。
回答
今回の提出と、以前のコードを見比べる形にします。自戒として。。
今回のコード
N, M = gets.chomp.split.map(&:to_i)
a_arr = gets.chomp.split.map(&:to_i)
b_arr = gets.chomp.split.map(&:to_i)
bm = b_arr.max
ids = Array.new(bm+1, -1)
N.times do |i|
e = a_arr[i] # eat_level的なe
if e <= bm
ids[e..bm] = Array.new((bm - e + 1), i+1)
bm = e - 1
end
break if bm <= 0
end
b_arr.each do |b|
puts ids[b]
end
前回のコード
N, M = gets.chomp.split(' ').map(&:to_i)
a_arr = gets.chomp.split(' ').map(&:to_i)
b_arr = gets.chomp.split(' ').map(&:to_i)
max_b = b_arr.max
r = max_b # 現状流れてくる最大値
ids = Array.new(r + 1, -1) # おいしさごと、誰が食べるか記録する配列
for i in 0...N do
person = i + 1
if a_arr[i] <= r
(a_arr[i]..r).each do |j|
ids[j] = person
end
r = a_arr[i] - 1
end
end
b_arr.each do |b|
puts ids[b]
end
差分
N, M = gets.chomp.split.map(&:to_i)
a_arr = gets.chomp.split.map(&:to_i)
b_arr = gets.chomp.split.map(&:to_i)
+ bm = b_arr.max
- max_b = b_arr.max
- r = max_b # 特に入れ直す必要がないため、bmとだけ置いてそれを利用しています。
ids = Array.new(bm+1, -1)
+ N.times do |i| # rubyらしく変更
+ e = a_arr[i] # eat_level的なeを取り出しておく
+ if e <= bm
+ ids[e..bm] = Array.new((bm - e + 1), i+1) # ループを回さず、範囲で置き換える
+ bm = e - 1
+ end
+ break if bm <= 0 # なくても良いが、それ以上の処理は不要なためbreak
+ end
- for i in 0...N do
- person = i + 1 # ここで取り出す必要があまりなさそう?
- if a_arr[i] <= r # 上でi+1をしているのに、こちらは普通に取り出している?となった。上は回答のため1indexを利用するため正しいが、少し紛らわしい。
- (a_arr[i]..r).each do |j| # 同じ値を入れるので、一気に置き換えて良さそう
- ids[j] = person
- end
- r = a_arr[i] - 1
- end
- end
b_arr.each do |b|
puts ids[b]
end
という感じでしょうか。
前回のコードも間違ってはいないのですが、久しぶりに見るとイマイチだったりします。
業務でも、その時の知識ではそれが最善と思っていても、たまに振り返るとより良さそうなコードでかけたりするかもななんて思います。