2018-12-14 23:36:29 +01:00

88 lines
2.2 KiB
Python
Executable File

#!/usr/bin/env python
from datetime import datetime
import re
RE_BEGIN = re.compile("^\[(.*)\] Guard #(\d+) begins shift$")
RE_SLEEP = re.compile("^\[(.*)\] falls asleep$")
RE_AWAKE = re.compile("^\[(.*)\] wakes up$")
guards = dict()
def read_input():
with open('input.txt', 'r') as f:
data = f.read().splitlines()
return sorted(data)
def convert_time(data):
return datetime.strptime(data, '%Y-%m-%d %H:%M')
def guard_stop_shift(guard, date):
guard_awake(guard, date)
def guard_start_shift(guard, date):
if guard is None:
return
if guard not in guards:
guards[guard] = {
'guard': guard,
'state': 'awake',
'min': [0]*60,
'sleep': 0,
'last_time': None
}
guard_awake(guard, date)
def guard_sleep(guard, date):
if guard is None:
return
guards[guard]['state'] = 'sleep'
guards[guard]['last_time'] = date
def guard_awake(guard, date):
if guard is None:
return
if guards[guard]['state'] in ['awake']:
guards[guard]['last_time'] = date
return
m = int((date - guards[guard]['last_time']).total_seconds() / 60)
m1 = guards[guard]['last_time'].minute
for x in range(m):
m2 = (x + m1) % 60
guards[guard]['min'][m2] += 1
guards[guard]['sleep'] += m
guards[guard]['state'] = 'awake'
guards[guard]['last_time'] = date
current_guard = None
for line in read_input():
m = RE_BEGIN.match(line)
if m:
d = convert_time(m.group(1))
guard_stop_shift(current_guard, d)
current_guard = (int)(m.group(2))
guard_start_shift(current_guard, d)
continue
m = RE_SLEEP.match(line)
if m:
d = convert_time(m.group(1))
guard_sleep(current_guard, d)
continue
m = RE_AWAKE.match(line)
if m:
d = convert_time(m.group(1))
guard_awake(current_guard, d)
continue
print(line)
raise Exception('unpasable line')
max_sleep = max(guards.values(), key=lambda i: i['sleep'])
max_min = max(max_sleep['min'])
max_min_pos = [i for i, j in enumerate(max_sleep['min']) if j == max_min]
print(max_sleep['guard'] * max_min_pos[0])