-
Notifications
You must be signed in to change notification settings - Fork 0
/
day04.rb
126 lines (104 loc) · 2.85 KB
/
day04.rb
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
require 'time'
require_relative 'toolbox'
class RecordKeeper
def initialize(f)
@filename = f
@h = Hash.new { |h, k| h[k] = Array.new(60, 0) }
end
# guard with the most sleep
def strat1
_generate_record if @h.empty?
sleepiest_guard_id = nil
max = 0
@h.each do |id, minutes|
total = minutes.reduce(&:+)
if max < total
max = total
sleepiest_guard_id = id
end
end
@h.select {|k,v| k == sleepiest_guard_id}
end
# guard with the most consistent sleep
def strat2
_generate_record if @h.empty?
gid = nil
max = 0
@h.each do |id, minutes|
peak = minutes.max
if max < peak
max = peak
gid = id
end
end
@h.select {|k,v| k == gid}
end
private
def _generate_record
id = nil
fall_asleep_time = nil
wake_up_time = nil
_clean_and_sorted_lines.each do |line|
date = Time.parse(line[/\[(.*?)\]/, 1])
id = line.split(' ')[3].split('#').last.to_i if line.include?("Guard")
if line.include?("Guard")
fall_asleep_time = nil
wake_up_time = nil
end
fall_asleep_time = date if line.include?("asleep")
wake_up_time = date if line.include?("wakes")
if line.include?("wakes")
# get the fall asleep minute
m_sleep = fall_asleep_time.strftime("%M").to_i
m_wake = wake_up_time.strftime("%M").to_i
(m_sleep...m_wake).each {|m| @h[id][m] += 1 }
end
end
end
def _clean_and_sorted_lines
raw_lines(@filename).sort! {|a,b|
da = Time.parse(a[/\[(.*?)\]/, 1])
db = Time.parse(b[/\[(.*?)\]/, 1])
da <=> db
}
end
end
def minute_with_most_sleep(guard)
minutes = guard.values.first
max_index = minutes.max
minutes.find_index(max_index)
end
def checksum(guard)
guard.keys.first * minute_with_most_sleep(guard)
end
def run_tests
test_data_file = "data/day04_test_duty_records.txt"
rk = RecordKeeper.new(test_data_file)
puts "Part 1: testing..."
expected = [240]
(0...expected.size).each do |n|
actual = checksum(rk.strat1)
if actual == expected[n]
puts "test #{n} passed"
else
puts "test #{n} failed! got #{actual} and expected #{expected[n]}"
end
end
puts "Part 2: testing..."
expected = [4455]
(0...expected.size).each do |n|
actual = checksum(rk.strat2)
if actual == expected[n]
puts "test #{n} passed"
else
puts "test #{n} failed! got #{actual} and expected #{expected[n]}"
end
end
end
run_tests
production_data_file = 'data/day04_production_duty_records.txt'
rk = RecordKeeper.new(production_data_file)
puts "Part 1: What is the ID of the guard you chose multiplied by the minute you chose?"
puts "Answer: #{checksum(rk.strat1)}"
puts "Part 2: What is the ID of the guard you chose multiplied by the minute you chose?"
puts "Answer: #{checksum(rk.strat2)}"