aboutsummaryrefslogtreecommitdiffstats
path: root/src/04/solve.py
blob: 0783b9b6e75d64c13ae740defd85072bcca8717b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import sys
sys.path.append("../common")
import aoc

data = aoc.data.split("\n")

def parse_entry(l):
    split = l.split(" ")
    date = " ".join(split[:2])
    time = int(split[1].split(":")[1].replace("]",""))
    if split[2] == "Guard":
        awake = None
        id = int(split[3].replace("#",""))
    else:
        id = 0
        awake = (True if split[2] == "wakes" else False)
    return time, id, awake, date

class guard:
    def __init__(self, _id):
        self.shifts = list()
        self.id = _id
        self.awake = None

def gen_shiftmap():
    shiftdata = [parse_entry(l) for l in data]
    shiftdata = sorted(shiftdata, key=lambda x: x[3]) # sort by date

    shiftmap = dict()
    ltime = shiftdata[0][0]
    cgid = shiftdata[0][1]
    for i in range(len(shiftdata)):
        entry = shiftdata[i]
        ctime = entry[0]
        gid = entry[1]
        cawake = entry[2]

        if gid != 0:
            if gid not in shiftmap:
                shiftmap[gid] = guard(gid)
            cgid = gid
        else:
            g = shiftmap[cgid]
            if cawake:
                if not g.awake:
                    shiftmap[cgid].shifts.append((ltime, ctime - ltime))
            else:
                ltime = ctime
            g.awake = cawake

    return shiftmap

def solve1(args):
    shiftmap = gen_shiftmap()

    maxsleep = None
    mg = None
    for g in shiftmap.values():
        minslept = 0
        for t in g.shifts:
            minslept += t[1]
        if not maxsleep or minslept > maxsleep:
            maxsleep = minslept
            mg = g


    timel = [0 for x in range(60)]

    for t in mg.shifts:
        for i in range(t[0], t[0] + t[1]):
            timel[(i-1)%60] += 1

    minute = timel.index(max(timel))+1

    return minute * mg.id

def solve2(args):
    shiftmap = gen_shiftmap()
    timetables = dict()

    for g in shiftmap.values():
        timetables[g.id] = [0 for x in range(60)]
        for t in g.shifts:
            for i in range(t[0], t[0] + t[1]):
                timetables[g.id][i] += 1

    mgid, mmin = max(((gid, i) for gid in timetables for i in range(60)),
            key = lambda x: timetables[x[0]][x[1]])

    return mgid * mmin

aoc.run(solve1, solve2, sols=[87681, 136461])