72 lines
1.8 KiB
Python
Executable File
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)
|