From b8a8a2155f7bbe1e15fda9103713ba88fa902503 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 6 Dec 2018 22:52:33 -0800 Subject: [PATCH] Add solutions for day 7 --- day7.cr | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 day7.cr diff --git a/day7.cr b/day7.cr new file mode 100644 index 0000000..8060dc5 --- /dev/null +++ b/day7.cr @@ -0,0 +1,87 @@ +require "./common.cr" + +lines = File.read("day7_input").split("\n") +lines.pop + +REGEX = /Step (.+) must be finished before step (.+) can begin./ + +all_children = {} of String => Set(String) +all = Set(String).new +finished = Set(String).new +finished_array = Array(String).new + +lines.map(&.match(REGEX)).each do |match| + match = match.not_nil! + child = match[1] + parent = match[2] + + all << child + all << parent + parent_set = all_children[parent]? || Set(String).new + parent_set << child + + all_children[parent] = parent_set +end + +available_at = {} of String => Int32 + +class String + def cost + return (self[0].bytes[0] - 'A'.bytes[0]).to_i32 + 1 + end +end + +def get_available(all, finished, children) + available = all.select do |it| + next false if finished.includes? it + next true unless set = children[it]? + next true if set.size == 0 + end +end + +children = all_children.clone +while finished.size != all.size + available = get_available(all, finished, children) + available.sort! + + first = available.first + finished << first + finished_array << first + + children.values.each do |value| + value.delete first + end +end +puts finished_array.join "" + +finished.clear +finished_array.clear +children = all_children.clone +workers = [0, 0, 0, 0, 0] +current_time = 0 +finished_at = {} of String => Int32 + +while finished.size < all.size + workers.each_with_index do |worker, index| + next if worker > current_time + + current_finished = finished_at.select { |k, v| v <= current_time }.map(&.[0]).to_set + available = all.select do |it| + next false if finished.includes? it + next true unless nodes = children[it]? + (nodes - current_finished).size == 0 + end + + available = available.sort! + next if available.empty? + + first = available.first + finished_at[first] = current_time + first.cost + 60 + workers[index] = current_time + first.cost + 60 + finished_array << first + finished << first + end + + current_time += 1 +end +puts finished_at.values.max