קישור לחידה המקורית:
https://adventofcode.com/2018/day/4
פיתרון שלי ברובי:
require 'time'
class Guard
attr_accessor :sleep_times
def initialize
self.sleep_times = [0] * 60
end
def start_sleep(timestamp)
@sleep_start = timestamp
end
def sleep_minutes
sleep_times.sum
end
def most_frequently_asleep_minute
sleep_times.each_with_index.max_by {|x| x[0]}
end
def end_sleep(sleep_end)
((sleep_end - @sleep_start)/60).to_i.times do |minute|
self.sleep_times[@sleep_start.min + minute] += 1
end
end
end
guards = {}
guards.default_proc = proc {|hash, key| hash[key] = Guard.new}
guard_id = nil
ARGF.each_line.sort.map(&:strip).each do |line|
timestamp = Time.parse(line.match(/^\[(\d+-\d+-\d+ \d+:\d+)\]/)[1])
if md = line.match(/Guard #(\d+)/)
guard_id = md[1].to_i
elsif line.match(/falls asleep/)
guards[guard_id].start_sleep(timestamp)
elsif line.match(/wakes up/)
guards[guard_id].end_sleep(timestamp)
end
end
# PART 1
puts "--- part 1"
sleepy_guard_id = guards.sort_by {|k, v| v.sleep_minutes }.last[0]
sleepy_minute = guards[sleepy_guard_id].sleep_times.each_with_index.max[1]
puts sleepy_guard_id * sleepy_minute
# PART 2
puts "--- part 1"
part_2 = guards.sort_by {|k, v| v.most_frequently_asleep_minute[0]}.last
puts part_2[0] * part_2[1].most_frequently_asleep_minute[1]
אני חושב שהגדרת קלאס כאן מאוד עזרה לסדר את המושגים. החישובים עצמם הם פשוטים ברגע ששומרים את המידע בצורה שקל לעבוד איתו