2018 day 4
This commit is contained in:
parent
1a5d5866fd
commit
b9c5a076a2
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env python3
|
||||
import fileinput
|
||||
import re
|
||||
import numpy as np
|
||||
from collections import namedtuple, defaultdict
|
||||
from datetime import datetime
|
||||
from enum import IntEnum
|
||||
|
||||
Log = namedtuple('Log', 'datetime, type, id')
|
||||
guard_id_pattern = re.compile(r'#(\d+)')
|
||||
|
||||
|
||||
class LogType(IntEnum):
|
||||
BeginShift = 0
|
||||
Asleep = 1
|
||||
WakeUp = 2
|
||||
|
||||
|
||||
def parse_log(log):
|
||||
log_date = datetime.strptime(log[1:17], '%Y-%m-%d %H:%M')
|
||||
log_type = None
|
||||
if log[19:] == 'falls asleep':
|
||||
return Log(log_date, LogType.Asleep, None)
|
||||
elif log[19:] == 'wakes up':
|
||||
return Log(log_date, LogType.WakeUp, None)
|
||||
return Log(log_date, LogType.BeginShift, int(next(guard_id_pattern.finditer(log[19:])).group(1)))
|
||||
|
||||
|
||||
def main():
|
||||
logs = sorted(map(parse_log, map(str.strip, fileinput.input())), key=lambda l: l.datetime)
|
||||
guards = {k: np.zeros(60) for k in set(filter(None, map(lambda l: l.id, logs)))}
|
||||
current_guard, asleep_time = None, None
|
||||
for log in logs:
|
||||
if log.type == LogType.BeginShift:
|
||||
assert not asleep_time
|
||||
current_guard = log.id
|
||||
elif log.type == LogType.Asleep:
|
||||
assert current_guard
|
||||
asleep_time = log.datetime
|
||||
elif log.type == LogType.WakeUp:
|
||||
assert current_guard
|
||||
assert asleep_time
|
||||
assert log.datetime > asleep_time
|
||||
guards[current_guard][asleep_time.minute:log.datetime.minute] += 1
|
||||
asleep_time = None
|
||||
else:
|
||||
raise ValueError('Log type not in enum')
|
||||
|
||||
# Part 1: Get the guard who slept the most
|
||||
sleepy_guard = sorted(guards, key=lambda k: np.sum(guards[k]), reverse=True)[0]
|
||||
part1 = sleepy_guard * guards[sleepy_guard].argmax()
|
||||
|
||||
# Part 2:
|
||||
# Get the guard who slept the most on the same minute
|
||||
sleepy_guard = sorted(guards, key=lambda k: guards[k].max(), reverse=True)[0]
|
||||
# Get the minute where this guard slept the most
|
||||
part2 = sleepy_guard * guards[sleepy_guard].argmax()
|
||||
|
||||
return part1, part2
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(main())
|
|
@ -0,0 +1 @@
|
|||
numpy>=1.15
|
Loading…
Reference in New Issue