AtCoder Beginner Contest 001
ABC001 解説 from AtCoder Inc.
www.slideshare.net
A - 積雪深差
h1 = gets.to_i h2 = gets.to_i puts h1 - h2
puts gets.to_i - gets.to_i
でもよし。
B - 視程の通報
m = gets.to_i if m < 100 puts "00" elsif m.between?(100, 5000) vv = m * 10 / 1000 puts vv < 10 ? "0#{vv}" : vv elsif m.between?(6000, 30000) puts m / 1000 + 50 elsif m.between?(35000, 70000) puts (m / 1000 - 30) / 5 + 80 elsif m > 70000 puts 89 end
- 2番目の条件節では、この後の問題Dでも使用する
String#%
を使ってもよかった - 最後の
puts 89
は、puts "89"
の方が明確で一貫性があった - 8行目で「interpreted as grouped expression」と警告メッセージが出たので、putsの引数が長いときには、カッコを付けるか、変数に格納してから出力するべき
mをkmに変換するときに数値を浮動小数点数にするべきか迷ったが、この問題においては整数のままでも問題にならないので、整数のまま処理した。
C - 風力観測
class Float def direction degree_table = [11.25...33.75, 33.75...56.25, 56.25...78.75, 78.75...101.25, 101.25...123.75, 123.75...146.25, 146.25...168.75, 168.75...191.25, 191.25...213.75, 213.75...236.25, 236.25...258.75, 258.75...281.25, 281.25...303.75, 303.75...326.25, 326.25...348.75, 0.0..360.0] direction_table = %w(NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW N) degree_table.each_with_index do |direction, i| return direction_table[i] if direction.include? self end end def wind_force wind_table = [0.0..0.2, 0.3..1.5, 1.6..3.3, 3.4..5.4, 5.5..7.9, 8.0..10.7, 10.8..13.8, 13.9..17.1, 17.2..20.7, 20.8..24.4, 24.5..28.4, 28.5..32.6, 32.7..200.0] wind_table.each_with_index {|wind, i| return i if wind.include? self } end end # deg(整数)を引数に取ってdir(文字列)を返す def deg_to_dir(deg) dir = (deg / 10.0).direction end # dis(整数)を引数に取ってw(整数)を返す def dis_to_w(dis) w = (dis / 60.0).round(1).wind_force end deg, dis = gets.split.map(&:to_i) dir = deg_to_dir(deg) w = dis_to_w(dis) dir = 'C' if w == 0 puts "#{dir} #{w}"
Float#direction
におけるブロック変数名direction
が、メソッド名と同じなので変えるべきdeg_to_dir
メソッド、dis_to_w
メソッドは値を返すだけなので、わざわざ変数を用いる必要はない
D - 感雨時刻の整理
class Array def round s, e = self s -= s % 5 unless s % 5 == 0 e += 5 - e % 5 unless e % 5 == 0 e += 40 if e.to_s =~ /60\z/ [s, e] end def merge return self if self.size <= 1 (self.size - 1).times do |i| if self[i+1][0] <= self[i][1] && self[i][0] <= self[i+1][1] self[i+1] = [[self[i][0], self[i+1][0]].min, [self[i][1], self[i+1][1]].max] self[i] = nil end end self.compact end end n = gets.to_i rainfall_times = [] n.times { rainfall_times << gets.split('-').map(&:to_i) } rainfall_times.map(&:round).sort_by(&:first).merge.each do |rainfall_time| puts "%04d-%04d" % [rainfall_time[0], rainfall_time[1]] end
- 時間を丸めるために、分数が60になったときに40を足して処理するのは、機転が利いていてよかった
Array#round
におけるいくつかのselfは省略できる(self.size
とself.compact
)
Array#merge
においてcompact
ではなくcompact!
を使っていたことで、Runtime Errorを発生させてしまい、ドツボにはまった。