aoc2018/day04.py

80 lines
2.3 KiB
Python

import datetime
from collections import defaultdict
from tools.aoc import AOCDay
from typing import Any
class Day(AOCDay):
inputs = [
[
(240, "test_input4_1"),
(95199, "input4")
],
[
(4455, "test_input4_1"),
(7887, "input4")
]
]
def get_guards(self) -> dict:
active_guard = 0
sleep_start = 0
guards = {}
for event in sorted(self.getInput()):
time, msg = event.split("] ")
timestamp = datetime.datetime.strptime(time, "[%Y-%m-%d %H:%M")
if msg.startswith("Guard"):
active_guard = int(msg.split()[1][1:])
if active_guard not in guards:
guards[active_guard] = {
'total': 0,
'minutes': defaultdict(int)
}
elif msg.startswith("falls asleep"):
if timestamp.hour == 0:
sleep_start = timestamp.minute
elif msg.startswith("wakes up"):
guards[active_guard]['total'] += timestamp.minute - sleep_start
for m in range(sleep_start, timestamp.minute):
guards[active_guard]['minutes'][m] += 1
return guards
def part1(self) -> Any:
guards = self.get_guards()
max_guard = 0
max_minutes = 0
most_minute = 0
for guard, data in guards.items():
if data['total'] < max_minutes:
continue
max_guard = guard
max_minutes = data['total']
most_minute = sorted(data['minutes'], key=lambda k: data['minutes'][k], reverse=True)[0]
return max_guard * most_minute
def part2(self) -> Any:
guards = self.get_guards()
max_guard = 0
max_minute = 0
max_time = 0
for guard, data in guards.items():
if not data['minutes']:
continue
most_minute = sorted(data['minutes'], key=lambda k: data['minutes'][k], reverse=True)[0]
if data['minutes'][most_minute] < max_time:
continue
max_guard = guard
max_time = data['minutes'][most_minute]
max_minute = most_minute
return max_guard * max_minute
if __name__ == '__main__':
day = Day(2018, 4)
day.run(verbose=True)