diff --git a/2018/day7-cleaned.py b/2018/day7-cleaned.py new file mode 100644 index 0000000..835467d --- /dev/null +++ b/2018/day7-cleaned.py @@ -0,0 +1,56 @@ +import logging +# logging.basicConfig(level=logging.DEBUG) +with open('day7-input', 'r') as file: + data = [l.strip('\n') for l in file] + +steps = set() +step_deps = {} +for line in data: + tokens = line.split() + step1, step2 = tokens[1], tokens[-3] + steps.update((step1, step2)) + step_deps[step2] = step_deps.get(step2, []) + [step1] + + +def assemble_sleigh(all_steps, step_dependencies, workers): + unprocessed_steps = all_steps.copy() + ready_steps = set() + constructing_steps = {} + completed_steps = set() + output = [] + + time = -1 + while unprocessed_steps: + time += 1 + for k in list(constructing_steps): + constructing_steps[k] -= 1 + if constructing_steps[k] < 1: + completed_steps.add(k) + output.append(k) + logging.debug(f'{time:04}: Step {k} complete!') + constructing_steps.pop(k) + + free_workers = workers - len(constructing_steps) + if free_workers < 1: + continue + + for step in unprocessed_steps - ready_steps: + dependencies = [d for d in step_dependencies.pop(step, []) if d not in completed_steps] + if dependencies: + step_dependencies[step] = dependencies + else: + ready_steps.add(step) + + for step in list(sorted(ready_steps))[:free_workers]: + constructing_steps[step] = 60 + ord(step) - 64 # ord('A') is 65 + logging.debug(f'{time:04}: Starting step {step}! ({constructing_steps[step]} seconds remain)') + unprocessed_steps.remove(step) + ready_steps.remove(step) + + output += [step for step, time in sorted(constructing_steps.items(), key=lambda x: x[1])] + time += max(constructing_steps.values()) + return ''.join(output), time + + +print('Solo - Order {}, completion time {:4d}s'.format(*assemble_sleigh(steps, step_deps.copy(), 1))) # Part 1, answer is order. +print('5man - Order {}, completion time {:4d}s'.format(*assemble_sleigh(steps, step_deps.copy(), 5))) # Part 2, answer is time.