#!/usr/bin/env python3 from functools import reduce from pprint import pprint with open('input.txt', 'r') as f: instructions = [x.strip() for x in f.readlines()] instructions = [(x.split(' ')[1], x.split(' ')[7]) for x in instructions] steps = {y for x in instructions for y in x} # flatten finished = list() requirements = { step: [] for step in steps } for el in instructions: requirements[el[1]].append(el[0]) def get_possible_steps(): possible = [ step for step in requirements if len(requirements[step]) == 0] possible.sort() return possible def calc_duration(step): return ord(step) - 64 + 60 def begin_step(step): steps.remove(step) requirements.pop(step) def finish_step(step): for el in requirements: if step in requirements[el]: requirements[el].remove(step) finished.append(step) def print_row(sec, states, fin): row = str(sec).ljust(4) + ' ' row += ' ' for state in states: row += '' + state + ' ' row += ''.join(fin) print(row) class Worker: def __init__(self): self.step = None self.duration = None def init_step(self, step): self.step = step self.duration = calc_duration(step) - 1 def get_state(self): if self.step is None: return '.' # idle self.duration -= 1 if self.duration > 0: return '#' # working _step = self.step self.step = None return _step # finished work workers = [Worker(), Worker(), Worker(), Worker(), Worker()] # hack buffer_finished = [] i = 0 while len(finished) != 26: for fin in buffer_finished: finish_step(fin) buffer_finished = [] states = [] for worker in workers: state = worker.get_state() if state not in ['#', '.']: buffer_finished.append(state) if state != '#': try: step = get_possible_steps().pop(0) begin_step(step) worker.init_step(step) state = step.lower() except IndexError: pass states.append(state) print_row(i, states, finished) i += 1 print(''.join(finished)) print('Duration', i - 1)