···11+import fileinput
22+from copy import deepcopy
33+from collections import defaultdict
44+55+66+def toposort(data):
77+ """
88+ Topological sort implementation via:
99+ https://bitbucket.org/ericvsmith/toposort/src/e63ddf93ccb68a7e33ba97680ecdb72ea9f96669/toposort.py
1010+ """
1111+ from functools import reduce as _reduce
1212+1313+ # Special case empty input.
1414+ if len(data) == 0:
1515+ return
1616+1717+ # Copy the input so as to leave it unmodified.
1818+ data = data.copy()
1919+2020+ # Ignore self dependencies.
2121+ for k, v in data.items():
2222+ v.discard(k)
2323+ # Find all items that don't depend on anything.
2424+ extra_items_in_deps = _reduce(set.union, data.values()) - set(data.keys())
2525+ # Add empty dependences where needed.
2626+ data.update({item:set() for item in extra_items_in_deps})
2727+ while True:
2828+ ordered = set(item for item, dep in data.items() if len(dep) == 0)
2929+ if not ordered:
3030+ break
3131+ yield ordered
3232+ data = {item: (dep - ordered) for item, dep in data.items() if item not in ordered}
3333+ if len(data) != 0:
3434+ raise Exception()
3535+3636+3737+def purge_val(graph, val):
3838+ for k in graph:
3939+ graph[k].discard(val)
4040+4141+ try:
4242+ del graph[val]
4343+ except Exception:
4444+ pass
4545+4646+4747+# Read problem input
4848+GRAPH = defaultdict(set)
4949+5050+for line in fileinput.input():
5151+ words = line.split()
5252+ a, b = words[1], words[7]
5353+ GRAPH[b].add(a)
5454+5555+5656+# Solve Part 1
5757+graph = deepcopy(GRAPH)
5858+order = ''
5959+6060+while graph:
6161+ candidates = sorted(''.join(next(toposort(graph))))
6262+ a = candidates[0]
6363+ order += a
6464+ purge_val(graph, a)
6565+6666+print "Instruction order:", order
6767+6868+6969+# Solve Part 2
7070+graph = deepcopy(GRAPH)
7171+workers = [('.', 0)] * 5
7272+queued = set()
7373+7474+time = 0
7575+done = ''
7676+7777+while True:
7878+ try:
7979+ okay = set(next(toposort(graph)))
8080+ except StopIteration:
8181+ break
8282+8383+ candidates = list(sorted(okay - queued, reverse=True))
8484+8585+ for i, (step, left) in enumerate(workers):
8686+ if step != '.' and left == 0:
8787+ done += step
8888+ purge_val(graph, step)
8989+ workers[i] = ('.', 0)
9090+ break
9191+ else:
9292+ for i, (step, left) in enumerate(workers):
9393+ if step == '.' and candidates:
9494+ a = candidates.pop()
9595+ queued.add(a)
9696+ workers[i] = (a, 60 + (ord(a) - ord('A')))
9797+ elif step != '.':
9898+ a, b = workers[i]
9999+ workers[i] = (a, b - 1)
100100+101101+ # print "t={}\tworkers={}\tdone={}".format(time, ' '.join(w[0] for w in workers), done)
102102+ time += 1
103103+104104+ continue
105105+106106+print "Time to complete all steps:", time
+101
2018/inputs/07.txt
···11+Step G must be finished before step S can begin.
22+Step T must be finished before step Q can begin.
33+Step A must be finished before step B can begin.
44+Step H must be finished before step X can begin.
55+Step V must be finished before step O can begin.
66+Step Z must be finished before step P can begin.
77+Step R must be finished before step J can begin.
88+Step L must be finished before step Y can begin.
99+Step Y must be finished before step E can begin.
1010+Step W must be finished before step X can begin.
1111+Step X must be finished before step B can begin.
1212+Step K must be finished before step E can begin.
1313+Step Q must be finished before step P can begin.
1414+Step U must be finished before step B can begin.
1515+Step M must be finished before step O can begin.
1616+Step P must be finished before step N can begin.
1717+Step I must be finished before step J can begin.
1818+Step B must be finished before step C can begin.
1919+Step C must be finished before step O can begin.
2020+Step J must be finished before step F can begin.
2121+Step F must be finished before step O can begin.
2222+Step E must be finished before step D can begin.
2323+Step D must be finished before step N can begin.
2424+Step N must be finished before step S can begin.
2525+Step S must be finished before step O can begin.
2626+Step W must be finished before step O can begin.
2727+Step L must be finished before step P can begin.
2828+Step N must be finished before step O can begin.
2929+Step T must be finished before step D can begin.
3030+Step G must be finished before step I can begin.
3131+Step V must be finished before step X can begin.
3232+Step B must be finished before step N can begin.
3333+Step R must be finished before step N can begin.
3434+Step H must be finished before step J can begin.
3535+Step B must be finished before step S can begin.
3636+Step P must be finished before step I can begin.
3737+Step A must be finished before step J can begin.
3838+Step A must be finished before step U can begin.
3939+Step B must be finished before step D can begin.
4040+Step T must be finished before step A can begin.
4141+Step U must be finished before step D can begin.
4242+Step T must be finished before step L can begin.
4343+Step I must be finished before step E can begin.
4444+Step R must be finished before step U can begin.
4545+Step H must be finished before step S can begin.
4646+Step P must be finished before step F can begin.
4747+Step Q must be finished before step C can begin.
4848+Step A must be finished before step P can begin.
4949+Step X must be finished before step E can begin.
5050+Step Q must be finished before step N can begin.
5151+Step E must be finished before step N can begin.
5252+Step Q must be finished before step O can begin.
5353+Step J must be finished before step S can begin.
5454+Step X must be finished before step P can begin.
5555+Step K must be finished before step U can begin.
5656+Step F must be finished before step E can begin.
5757+Step C must be finished before step E can begin.
5858+Step H must be finished before step K can begin.
5959+Step W must be finished before step B can begin.
6060+Step G must be finished before step O can begin.
6161+Step F must be finished before step N can begin.
6262+Step I must be finished before step D can begin.
6363+Step G must be finished before step V can begin.
6464+Step E must be finished before step S can begin.
6565+Step Y must be finished before step P can begin.
6666+Step G must be finished before step E can begin.
6767+Step P must be finished before step J can begin.
6868+Step U must be finished before step N can begin.
6969+Step U must be finished before step F can begin.
7070+Step X must be finished before step U can begin.
7171+Step X must be finished before step C can begin.
7272+Step R must be finished before step Q can begin.
7373+Step Q must be finished before step E can begin.
7474+Step Z must be finished before step E can begin.
7575+Step X must be finished before step F can begin.
7676+Step J must be finished before step D can begin.
7777+Step X must be finished before step M can begin.
7878+Step Y must be finished before step D can begin.
7979+Step K must be finished before step J can begin.
8080+Step Z must be finished before step J can begin.
8181+Step M must be finished before step P can begin.
8282+Step T must be finished before step M can begin.
8383+Step F must be finished before step S can begin.
8484+Step P must be finished before step S can begin.
8585+Step X must be finished before step I can begin.
8686+Step U must be finished before step J can begin.
8787+Step M must be finished before step B can begin.
8888+Step Q must be finished before step D can begin.
8989+Step Z must be finished before step I can begin.
9090+Step D must be finished before step S can begin.
9191+Step J must be finished before step N can begin.
9292+Step D must be finished before step O can begin.
9393+Step T must be finished before step H can begin.
9494+Step P must be finished before step D can begin.
9595+Step M must be finished before step F can begin.
9696+Step Y must be finished before step S can begin.
9797+Step H must be finished before step I can begin.
9898+Step Y must be finished before step W can begin.
9999+Step X must be finished before step J can begin.
100100+Step L must be finished before step W can begin.
101101+Step G must be finished before step N can begin.