You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
2.5 KiB
Python
96 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import re
|
|
from datetime import datetime, timedelta
|
|
from pprint import pprint
|
|
|
|
with open('input.txt', 'r') as f:
|
|
notes_raw = [x.strip() for x in f.readlines()]
|
|
|
|
regex = re.compile(r'\[(.*)\] (.*)')
|
|
|
|
notes_timestamped = list()
|
|
for note in notes_raw:
|
|
matches = regex.match(note)
|
|
notes_timestamped.append(
|
|
(datetime.strptime(matches[1], "%Y-%m-%d %H:%M"), matches[2])
|
|
)
|
|
|
|
notes_timestamped.sort()
|
|
|
|
# pprint(notes_timestamped)
|
|
|
|
def mark_map(my_map, mode, start, end):
|
|
for i in range(start, end):
|
|
my_map[i] = '.' if mode == 'awake' else '#'
|
|
|
|
class Entry:
|
|
def __init__(self, guard_id):
|
|
self.guard_id = guard_id
|
|
self.notes = list()
|
|
self._awake_map = None
|
|
|
|
def get_date(self):
|
|
date = self.notes[0][0]
|
|
if date.hour == 23:
|
|
date = date + timedelta(days=1)
|
|
return date.strftime('%m-%d')
|
|
|
|
def get_awake_map(self):
|
|
if self._awake_map is not None:
|
|
return self._awake_map
|
|
mode = 'awake'
|
|
awake_map = ['?'] * 60
|
|
|
|
start = 0 if self.notes[0][0].hour == 23 else self.notes[0][0].minute
|
|
|
|
for note in self.notes[1:]:
|
|
minute = note[0].minute
|
|
mark_map(awake_map, mode, start, minute)
|
|
start = minute
|
|
mode = 'awake' if note[1] == 'wakes up' else 'asleep'
|
|
|
|
mark_map(awake_map, mode, start, 60)
|
|
self._awake_map = awake_map
|
|
return awake_map
|
|
|
|
def __repr__(self):
|
|
return '{} #{} {}'.format(self.get_date(), self.guard_id.rjust(4), ''.join(self.get_awake_map()))
|
|
|
|
|
|
regex = re.compile(r'#(\d*)')
|
|
days = list()
|
|
|
|
current_entry = None
|
|
for note in notes_timestamped:
|
|
action = note[1]
|
|
matches = regex.search(action)
|
|
|
|
if matches:
|
|
current_entry = Entry(matches[1])
|
|
days.append(current_entry)
|
|
|
|
current_entry.notes.append(note)
|
|
|
|
for day in days:
|
|
print(day)
|
|
|
|
# Number of sleep per guard per minute
|
|
sleep_count = dict()
|
|
for day in days:
|
|
awake_map = day.get_awake_map()
|
|
for i in range(0, 60):
|
|
idx = f'{day.guard_id}-{i}'
|
|
if sleep_count.get(idx) is None:
|
|
sleep_count[idx] = 0
|
|
if awake_map[i] == '#':
|
|
sleep_count[idx] += 1
|
|
# pprint(sleep_count)
|
|
|
|
sleepy_idx = max(sleep_count, key=sleep_count.get)
|
|
sleepy_guard, sleepy_minute = sleepy_idx.split('-')
|
|
print('Sleepy Guard:', sleepy_guard)
|
|
print('Sleepy Minute:', sleepy_minute)
|
|
res = int(sleepy_guard) * int(sleepy_minute)
|
|
print(f'{sleepy_guard} * {sleepy_minute} = {res}')
|