Add solutions for day 7
This commit is contained in:
parent
b0e079de0f
commit
b8a8a2155f
87
day7.cr
Normal file
87
day7.cr
Normal file
|
@ -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
Block a user