1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Reindeer
  attr_reader *%i[ speed time rest ]

  def initialize(speed, time, rest)
    @speed, @time, @rest = [speed, time, rest].map(&:to_i)
  end

  def distance(current_time)
    distance = speed * time
    total_time = time + rest
    reps = current_time / total_time

    reps * distance + [current_time % total_time, time].min * speed
  end
end

regex = /(\w+) can fly (\d+) km\/s for (\d+) seconds, but then must rest for (\d+) seconds/
reindeer = DATA.read.scan(regex).each.with_object({}) {|(name, speed, time, rest), reindeer|
  reindeer[name] = Reindeer.new(speed, time, rest)
}

scores = (1..2503).each.with_object(Hash.new(0)) do |current_time, scores|
  sorted = reindeer.group_by {|_,r| r.distance(current_time) }.sort
  sorted.last.last.map(&:first).each do |name|
    scores[name] += 1
  end
end

puts scores.sort_by(&:last)
__END__