parent
b0e079de0f
commit
b8a8a2155f
@ -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 |
Loading…
Reference in new issue