solve.py (2346B)
1import sys 2sys.path.append("../common") 3import aoc 4 5data = aoc.data.split("\n") 6 7def parse_entry(l): 8 split = l.split(" ") 9 date = " ".join(split[:2]) 10 time = int(split[1].split(":")[1].replace("]","")) 11 if split[2] == "Guard": 12 awake = None 13 id = int(split[3].replace("#","")) 14 else: 15 id = 0 16 awake = (True if split[2] == "wakes" else False) 17 return time, id, awake, date 18 19class guard: 20 def __init__(self, _id): 21 self.shifts = list() 22 self.id = _id 23 self.awake = None 24 25def gen_shiftmap(): 26 shiftdata = [parse_entry(l) for l in data] 27 shiftdata = sorted(shiftdata, key=lambda x: x[3]) # sort by date 28 29 shiftmap = dict() 30 ltime = shiftdata[0][0] 31 cgid = shiftdata[0][1] 32 for i in range(len(shiftdata)): 33 entry = shiftdata[i] 34 ctime = entry[0] 35 gid = entry[1] 36 cawake = entry[2] 37 38 if gid != 0: 39 if gid not in shiftmap: 40 shiftmap[gid] = guard(gid) 41 cgid = gid 42 else: 43 g = shiftmap[cgid] 44 if cawake: 45 if not g.awake: 46 shiftmap[cgid].shifts.append((ltime, ctime - ltime)) 47 else: 48 ltime = ctime 49 g.awake = cawake 50 51 return shiftmap 52 53def solve1(args): 54 shiftmap = gen_shiftmap() 55 56 maxsleep = None 57 mg = None 58 for g in shiftmap.values(): 59 minslept = 0 60 for t in g.shifts: 61 minslept += t[1] 62 if not maxsleep or minslept > maxsleep: 63 maxsleep = minslept 64 mg = g 65 66 67 timel = [0 for x in range(60)] 68 69 for t in mg.shifts: 70 for i in range(t[0], t[0] + t[1]): 71 timel[(i-1)%60] += 1 72 73 minute = timel.index(max(timel))+1 74 75 return minute * mg.id 76 77def solve2(args): 78 shiftmap = gen_shiftmap() 79 timetables = dict() 80 81 for g in shiftmap.values(): 82 timetables[g.id] = [0 for x in range(60)] 83 for t in g.shifts: 84 for i in range(t[0], t[0] + t[1]): 85 timetables[g.id][i] += 1 86 87 mgid, mmin = max(((gid, i) for gid in timetables for i in range(60)), 88 key = lambda x: timetables[x[0]][x[1]]) 89 90 return mgid * mmin 91 92aoc.run(solve1, solve2, sols=[87681, 136461])