aboutsummaryrefslogtreecommitdiffstats
path: root/src/07/solve.py
blob: 8d7c708998550d8754f57832089925dd678770f4 (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
93
94
95
96
97
98
99
100
101
102
103
104
105
import sys
sys.path.append("../common")
import aoc

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

def remove_reqs(req, insts):
    for res in insts:
        if req in insts[res]:
            insts[res].remove(req)

def parse_entry(l):
    split = l.split(" ")
    firstl = split[1]
    nextl = split[-3]
    return firstl, nextl

def gen_insts():
    global data
    data = [parse_entry(l) for l in data if len(l) != 0]

    insts = dict()

    for ins in data:
        req = ins[0]
        res = ins[1]
        if res not in insts:
            insts[res] = [ req ]
        else:
            insts[res].append(req)

    values = list(insts.values())[:]
    for reslist in values:
        for res in reslist:
            if res not in insts:
                insts[res] = []

    return insts

def overlap(arr1, arr2):
    for a1 in arr1:
        if a1 in arr2:
            return True
    return False

def checkfail(workers):
    done = True
    for w in workers:
        if w[2]:
            done = False
            break
    return done

def solve1(args):
    insts = gen_insts()

    i = 0
    plan = list()
    while i < len(insts):
        res = sorted(insts.keys())[i] # alphabetically
        if len(insts[res]) == 0:
            plan.append(res)
            insts.pop(res, None)
            remove_reqs(res, insts)
            i = 0
        else:
            i += 1

    return "".join(plan)

def solve2(args):
    insts = gen_insts()

    # worker: (task, time, done)
    workers = [["", 0, False] for x in range(5)]

    time = -1
    stop = False
    while not stop:
        time += 1
        for i in range(len(workers)):
            w = workers[i]
            if time >= w[1]:
                if w[2]:
                    remove_reqs(w[0], insts)
                    aoc.debug("end : " + str(i) + " - " + str((w[0], w[1])))
                    w[2] = False
                    if len(insts) == 0 and checkfail(workers):
                        stop = True
                        break

        for i in range(len(workers)):
            w = workers[i]
            if time >= w[1]:
                for res in sorted(insts.keys()):
                    if len(insts[res]) == 0:
                        wtime = time + ord(res)-65+1 + 60
                        aoc.debug("start : " + str(i) + " - " + str((res, time)))
                        w[:] = (res, wtime, True)
                        insts.pop(res, None)
                        break

    return time

aoc.run(solve1, solve2, sols=["JNOIKSYABEQRUVWXGTZFDMHLPC", 1099])