re: AoC Day 4: Repose Record VIEW POST

FULL DISCUSSION
 

Had an afterwork event that included drinks which didn't mix well with the problem description ;-) Also it's past midnight here by now, so it's not exactly the most elegant code:

require 'date'

TIMESTAMP_REGEX = /\d{4}-\d{2}-\d{2} \d{2}:\d{2}/.freeze
ID_REGEX = /#(?<id>\d+)/.freeze
MINUTE_REGEX = /(?<minutes>\d\d)\]/.freeze

records = DATA.readlines.sort_by { |line| DateTime.parse(line[TIMESTAMP_REGEX]) }
grouped_records = records.chunk_while { |_l1, l2| l2 !~ /Guard/ }

sleep_ranges = Hash.new { |h, k| h[k] = [] }
grouped_records.each do |records|
  guard_id = records.shift.match(ID_REGEX)[:id].to_i
  sleep_ranges[guard_id] += records.each_slice(2).map { |period|
    Range.new(
      *period.map { |entry| entry.match(MINUTE_REGEX)[:minutes].to_i },
      true
    )
  }
end

sleep_minutes = sleep_ranges.map { |id, ranges|
  [
    id,
    (0..59).each_with_object(Hash.new(0)) { |minute, counts|
      counts[minute] = ranges.count { |r| r.include?(minute) }
    }
  ]
}.to_h

id, = sleep_ranges.max_by { |_, rs| rs.sum(&:size) }
puts id * sleep_minutes[id].max_by(&:last).first

id, minutes = sleep_minutes.max_by { |id, minutes| minutes.max_by(&:last).last }
puts id * minutes.max_by(&:last).first

__END__
[1518-06-25 23:58] Guard #1069 begins shift
[1518-09-16 00:24] falls asleep
[1518-04-06 00:56] wakes up
...
code of conduct - report abuse