adventofcode-2018/07/solve02.py
2018-12-14 23:36:29 +01:00

72 lines
1.8 KiB
Python
Executable File

#!/usr/bin/env python
import re
RE_LINE = re.compile('^Step (.*) must be finished before step (.*) can begin.')
WORKERS=5
JOB_TIME=60
tree = dict()
def read_input():
with open('input.txt', 'r') as f:
for line in f:
yield line
def add_dependency(a, b):
if a not in tree:
tree[a] = {
'node': a,
'parent': '',
'child': '',
'time': JOB_TIME+ord(a)-64
}
if b not in tree:
tree[b] = {
'node': b,
'parent': '',
'child': '',
'time': JOB_TIME+ord(b)-64
}
tree[a]['child'] += b
tree[b]['parent'] += a
for l in read_input():
m = RE_LINE.match(l)
if m is None:
raise Exception('unpaseable line')
add_dependency(m.group(1), m.group(2))
worker = [[0, None]] * WORKERS # time and job
total_time = 0
while len(tree):
# finish worker job
try:
min_time = min([x[0] for x in worker if x[0]>0])
total_time = min_time
except ValueError:
min_time = -1
min_workers = [ k for k,v in enumerate(worker) if v[0] == min_time]
for w in min_workers:
job = worker[w][1]
if job is None:
continue
for c in tree[job]['child']:
tree[c]['parent'] = tree[c]['parent'].replace(job, "")
del tree[job]
worker[w] = [0, None]
print('finish job for {}({})'.format(w, job))
# add new job
roots = sorted([ n['node'] for n in tree.values() if len(n['parent']) == 0 and n['time']>0])
empty_w = [ k for k,v in enumerate(worker) if v[1] is None]
for w in empty_w:
if len(roots) == 0:
break
job = roots.pop(0)
worker[w] = (total_time+tree[job]['time'], job)
tree[job]['time'] = 0
print('added job for {}({})'.format(w, job))
print(total_time)