-
Notifications
You must be signed in to change notification settings - Fork 0
/
07.py
74 lines (57 loc) · 1.65 KB
/
07.py
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
from lib import *
input = read_input(2018, 7)
unlocks = {}
requirements = {}
chars = set()
for line in input.splitlines():
a, b = re.match("^Step (.) must be finished before step (.) can begin\.$", line).groups()
chars |= {a, b}
unlocks.setdefault(a, set()).add(b)
requirements.setdefault(b, set()).add(a)
out = ""
Q = [e for e in chars if e not in requirements]
heapq.heapify(Q)
while Q:
p = heapq.heappop(Q)
out += p
for q in unlocks.get(p, []):
requirements[q].remove(p)
if not requirements[q]:
heapq.heappush(Q, q)
print(out)
unlocks = {}
requirements = {}
chars = set()
for line in input.splitlines():
a, b = re.match("^Step (.) must be finished before step (.) can begin\.$", line).groups()
chars |= {a, b}
unlocks.setdefault(a, set()).add(b)
requirements.setdefault(b, set()).add(a)
Q = [e for e in chars if e not in requirements]
seconds = 0
def get_task():
if Q:
task = Q.pop()
return (task, ord(task) - 4)
def finish_task(p):
for q in unlocks.get(p, []):
requirements[q].remove(p)
if not requirements[q]:
Q.append(q)
def fast_forward():
t = min((w[1] for w in workers if w is not None), default=0)
for i in range(5):
if workers[i] is None:
continue
workers[i] = workers[i][0], workers[i][1] - t
if workers[i][1] <= 0:
finish_task(workers[i][0])
workers[i] = None
return t
workers = [None for _ in range(5)]
while Q or any(workers):
seconds += fast_forward()
for i in range(5):
if workers[i] is None:
workers[i] = get_task()
print(seconds)