diff options
author | romangraef <romangraef@loves.dicksinhisan.us> | 2018-12-09 19:51:00 +0100 |
---|---|---|
committer | romangraef <romangraef@loves.dicksinhisan.us> | 2018-12-09 19:51:00 +0100 |
commit | 9437273f37353aded6f8caa844ebe23765dd6260 (patch) | |
tree | f86f54e4ec665fd7eab301fd4e878a4326c843ac /day7 | |
parent | 98ed1890f58698d8f6df9457c95908125a565b5f (diff) | |
download | aoc2018-9437273f37353aded6f8caa844ebe23765dd6260.tar.gz aoc2018-9437273f37353aded6f8caa844ebe23765dd6260.tar.bz2 aoc2018-9437273f37353aded6f8caa844ebe23765dd6260.zip |
Diffstat (limited to 'day7')
-rw-r--r-- | day7/solve.py | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/day7/solve.py b/day7/solve.py new file mode 100644 index 0000000..93ae801 --- /dev/null +++ b/day7/solve.py @@ -0,0 +1,74 @@ +from collections import defaultdict + +from commons import get_input, remove_empty + + +def get_requirement(line): + return line[5], line[36] + + +def fill_requirements(): + for line in lines: + needs, gives = get_requirement(line) + requirements[gives].append(needs) + _ = requirements[needs] # to insert all steps, even the ones without gives/needs + + +def find_available_steps(known, done): + return [ + gives for gives, needs in requirements.items() + if gives in known or all(need in done for need in needs) + ] + + +def find_order(): + done = set() + available = set() + steps = [] + while True: + available = set(find_available_steps(available, done)) + found = available - set(steps) + if len(found) == 0: + break + step = sorted(found)[0] + steps.append(step) + done.add(step) + return steps + + +def process_order(): + done = set() + available = set() + time = 0 + steps = [] + worker = [] + + while True: + print(time) + available = set(find_available_steps(available, done)) + found = available - set(steps) - set(map(lambda w: w[0], worker)) + if len(worker) == 0 and len(found) == 0: + break + for i in range(len(worker)): + job, passed = worker[i] + worker[i] = job, passed + 1 + + finished = list(filter(lambda w: w[1] >= ord(w[0]) - ord('A') + 60, worker)) + for d in finished: + done.add(d[0]) + steps.append(d[0]) + worker = list(filter(lambda w: w[1] < ord(w[0]) - ord('A') + 60, worker)) + + for job in list(found)[:5 - len(worker)]: + worker.append((job, 0)) + time += 1 + return time + + +lines = remove_empty(get_input(7).splitlines(keepends=False)) +requirements = defaultdict(list) +fill_requirements() + +if __name__ == '__main__': + print('first:', ''.join(find_order())) + print('second:', process_order()) |