aboutsummaryrefslogtreecommitdiff
path: root/day7
diff options
context:
space:
mode:
authorromangraef <romangraef@loves.dicksinhisan.us>2018-12-09 19:51:00 +0100
committerromangraef <romangraef@loves.dicksinhisan.us>2018-12-09 19:51:00 +0100
commit9437273f37353aded6f8caa844ebe23765dd6260 (patch)
treef86f54e4ec665fd7eab301fd4e878a4326c843ac /day7
parent98ed1890f58698d8f6df9457c95908125a565b5f (diff)
downloadaoc2018-9437273f37353aded6f8caa844ebe23765dd6260.tar.gz
aoc2018-9437273f37353aded6f8caa844ebe23765dd6260.tar.bz2
aoc2018-9437273f37353aded6f8caa844ebe23765dd6260.zip
Diffstat (limited to 'day7')
-rw-r--r--day7/solve.py74
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())