day 7
This commit is contained in:
parent
e4d4c533f1
commit
7348f78a09
|
@ -0,0 +1,75 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
|
||||
from time import sleep
|
||||
from pprint import pprint
|
||||
from collections import namedtuple, defaultdict
|
||||
|
||||
|
||||
# Node = NamedTuple("Node", "id blocks")
|
||||
|
||||
|
||||
def main():
|
||||
relations = defaultdict(lambda: set()) # mapping of step ID to what theyre blocked by
|
||||
steps = set()
|
||||
|
||||
with open("input.txt") as f:
|
||||
for line in f.readlines():
|
||||
_, stepid, _, _, _, _, _, blocks, _, _ = line.split()
|
||||
relations[blocks].update([stepid])
|
||||
# relations[stepid].append(blocks)
|
||||
steps.update([blocks, stepid])
|
||||
|
||||
# relations = dict(relations)
|
||||
|
||||
# pprint(steps)
|
||||
# pprint(dict(relations))
|
||||
|
||||
# while steps:
|
||||
# sleep(1)
|
||||
# print()
|
||||
# print(relations)
|
||||
# print(steps)
|
||||
# for step in list(steps):
|
||||
# if step not in relations or not relations[step]:
|
||||
# print("do ", step)
|
||||
# steps.remove(step)
|
||||
# for otherstep, blockers in relations.items():
|
||||
# if step in blockers:
|
||||
# blockers.remove(step)
|
||||
# break
|
||||
# break
|
||||
# if step in relations:
|
||||
# relations[step].remove(step)
|
||||
|
||||
remaining = sorted(list(steps))
|
||||
complete = set()
|
||||
|
||||
while remaining:
|
||||
# print()
|
||||
# print(remaining)
|
||||
# print(dict(relations))
|
||||
# Find unblocked step
|
||||
for step in remaining[:]:
|
||||
if not relations[step]:
|
||||
# print(step, "is unblocked")
|
||||
print(step, end="")
|
||||
complete.update(step)
|
||||
for k, v in relations.items():
|
||||
if step in v:
|
||||
v.remove(step)
|
||||
remaining.remove(step)
|
||||
break
|
||||
|
||||
|
||||
# def donext():
|
||||
# for step in remaining:
|
||||
# pass
|
||||
# pass
|
||||
|
||||
# donext()
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
|
||||
from time import sleep
|
||||
from pprint import pprint
|
||||
from collections import namedtuple, defaultdict
|
||||
|
||||
|
||||
class Job(object):
|
||||
def __init__(self, id, reqs, duration):
|
||||
self.id = id
|
||||
self.reqs = reqs
|
||||
self.duration = duration
|
||||
|
||||
def __repr__(self):
|
||||
return "<Job '{}'' ({}s) reqs:{}>".format(self.id, self.duration, self.reqs)
|
||||
|
||||
|
||||
class Worker(object):
|
||||
def __init__(self):
|
||||
self.task = None
|
||||
self.busy = 0
|
||||
|
||||
def __repr__(self):
|
||||
return "<Worker {} (busy for {}s) (job:{})>".format(id(self), self.busy, self.task)
|
||||
|
||||
|
||||
def main():
|
||||
num_workers = 5
|
||||
jobs = {}
|
||||
|
||||
def makejob(jobid):
|
||||
if jobid not in jobs:
|
||||
jobs[jobid] = Job(jobid, set(), ord(jobid) - 64 + 60)
|
||||
|
||||
with open("input.txt") as f:
|
||||
for line in f.readlines():
|
||||
_, stepid, _, _, _, _, _, blocks, _, _ = line.split()
|
||||
|
||||
makejob(stepid)
|
||||
makejob(blocks)
|
||||
|
||||
jobs[blocks].reqs.update([stepid])
|
||||
|
||||
|
||||
workers = [Worker() for i in range(0, num_workers)]
|
||||
empty = set()
|
||||
|
||||
duration = 0
|
||||
completed = set()
|
||||
while True:
|
||||
print()
|
||||
# pprint(jobs)
|
||||
# print(workers)
|
||||
# do worker accounting
|
||||
remainings = [worker.busy for worker in workers if worker.task is not None]
|
||||
if remainings:
|
||||
next_done = min(remainings)
|
||||
# print("next task done in", next_done, "s")
|
||||
duration += next_done
|
||||
|
||||
for worker in workers:
|
||||
if worker.task:
|
||||
worker.busy -= next_done
|
||||
if worker.busy == 0:
|
||||
print("finished", worker.task)
|
||||
completed.update([worker.task.id])
|
||||
worker.task = None
|
||||
|
||||
print("total = ", duration)
|
||||
|
||||
if not jobs:
|
||||
break
|
||||
|
||||
# find available tasks
|
||||
available = [task for taskid, task in jobs.items() if task.reqs.issubset(completed)]
|
||||
|
||||
# sort by weight
|
||||
available.sort(key=lambda x: x.duration)
|
||||
# print("can do:", available)
|
||||
# return
|
||||
|
||||
for worker in workers:
|
||||
if worker.task is None:
|
||||
if not available:
|
||||
break
|
||||
task = available.pop()
|
||||
worker.task = task
|
||||
worker.busy = task.duration
|
||||
# print("assigned {} to {}")
|
||||
print("assigned:", worker)
|
||||
del jobs[task.id]
|
||||
|
||||
print(duration)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue