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