#!/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() 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): 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) 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 minutes per guard sleep_count = dict() for day in days: guard_id = day.guard_id if sleep_count.get(guard_id) is None: sleep_count[guard_id] = 0 sleep_count[guard_id] += day.get_awake_map().count('#') # pprint(sleep_count) sleepy_guard = max(sleep_count, key=sleep_count.get) print('Sleepy guard:', sleepy_guard) # Number of sleep per minute minute_count = dict() for i in range(0, 60): minute_count[i] = 0 for day in days: if day.guard_id == sleepy_guard: awake_map = day.get_awake_map() for i in range(0, 60): if awake_map[i] == '#': minute_count[i] += 1 # pprint(minute_count) sleepy_minute = max(minute_count, key=minute_count.get) print('Sleepy Minute:', sleepy_minute) res = int(sleepy_guard) * sleepy_minute print(f'{sleepy_guard} * {sleepy_minute} = {res}')