Day 7
This commit is contained in:
parent
f677b1326e
commit
3203eeb9c3
|
@ -0,0 +1,113 @@
|
||||||
|
defmodule Day7 do
|
||||||
|
|
||||||
|
def get_requirement(str) do
|
||||||
|
[_, requirement, step] = Regex.run(~r/Step (\w) must be finished before step (\w) can begin./, str)
|
||||||
|
{step, requirement}
|
||||||
|
end
|
||||||
|
|
||||||
|
def all_nodes(requirements) do
|
||||||
|
requirements
|
||||||
|
|> Enum.reduce([], fn {step, req}, acc ->
|
||||||
|
[step | [req | acc]]
|
||||||
|
end)
|
||||||
|
|> Enum.uniq
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_graph(requirements) do
|
||||||
|
Enum.reduce(requirements, %{}, fn {step, req}, acc ->
|
||||||
|
Map.update(acc, step, [req], &([req | &1]))
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Topological sort implemented using Kahn's algorithm: https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm
|
||||||
|
"""
|
||||||
|
def kahn(_nodes, sorted, _graph, []), do: Enum.reverse(sorted)
|
||||||
|
def kahn(nodes, sorted, graph, no_incoming_edges) do
|
||||||
|
# sort no_incoming_edges lexicographically as per AoC problem
|
||||||
|
[n | rest_no_incoming_edges] = no_incoming_edges |> Enum.sort()
|
||||||
|
sorted = [n | sorted]
|
||||||
|
{graph, no_incoming_edges} =
|
||||||
|
nodes
|
||||||
|
|> Enum.filter(fn m -> n in Map.get(graph, m, []) end)
|
||||||
|
|> Enum.reduce({graph, rest_no_incoming_edges}, fn m, {graph, no_incoming_edges} ->
|
||||||
|
new_dependencies_of_m = graph |> Map.get(m) |> List.delete(n)
|
||||||
|
new_graph = graph |> Map.put(m, new_dependencies_of_m)
|
||||||
|
{
|
||||||
|
new_graph,
|
||||||
|
case new_dependencies_of_m do
|
||||||
|
[] -> [m | no_incoming_edges]
|
||||||
|
_ -> no_incoming_edges
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
kahn(nodes, sorted, graph, no_incoming_edges)
|
||||||
|
end
|
||||||
|
|
||||||
|
def kahn(nodes, graph) do
|
||||||
|
no_incoming_edges = Enum.filter(nodes, fn node -> !Map.has_key?(graph, node) end)
|
||||||
|
kahn(nodes, [], graph, no_incoming_edges)
|
||||||
|
end
|
||||||
|
|
||||||
|
def step_time(nil), do: 0
|
||||||
|
def step_time(<<c::utf8, _rest::binary>>) do
|
||||||
|
# step - ?A + 1 + extra
|
||||||
|
c - ?A + 60
|
||||||
|
end
|
||||||
|
|
||||||
|
def tick(workers, nodes, graph, done \\ [], time \\ 0) do
|
||||||
|
{workers, {done, nodes}} =
|
||||||
|
Enum.map_reduce(workers, {done, nodes}, fn {current_step, remaining}, {done, nodes} ->
|
||||||
|
case remaining do
|
||||||
|
0 ->
|
||||||
|
new_done = case current_step do
|
||||||
|
nil -> done
|
||||||
|
_ -> [current_step | done]
|
||||||
|
end
|
||||||
|
next_step =
|
||||||
|
nodes
|
||||||
|
|> Enum.find(fn node ->
|
||||||
|
Enum.all?(Map.get(graph, node, []), fn dep -> dep in new_done end)
|
||||||
|
end)
|
||||||
|
new_nodes = List.delete(nodes, next_step)
|
||||||
|
{{next_step, step_time(next_step)}, {new_done, new_nodes}}
|
||||||
|
|
||||||
|
n when n > 0 ->
|
||||||
|
{{current_step, n - 1}, {done, nodes}}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
IO.inspect(nodes)
|
||||||
|
IO.inspect(done)
|
||||||
|
IO.inspect(workers)
|
||||||
|
|
||||||
|
if length(nodes) == 0 and Enum.all?(workers, fn {step, _} -> step == nil end) do
|
||||||
|
time - 1
|
||||||
|
else
|
||||||
|
tick(workers, nodes, graph, done, time + 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_input() do
|
||||||
|
File.read!("lib/day7/input.txt")
|
||||||
|
|> String.split("\n", trim: true)
|
||||||
|
|> Enum.map(&get_requirement/1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def part1() do
|
||||||
|
requirements = parse_input()
|
||||||
|
nodes = all_nodes(requirements)
|
||||||
|
graph = create_graph(requirements)
|
||||||
|
kahn(nodes, graph)
|
||||||
|
|> Enum.join()
|
||||||
|
end
|
||||||
|
|
||||||
|
def part2() do
|
||||||
|
requirements = parse_input()
|
||||||
|
nodes = all_nodes(requirements)
|
||||||
|
graph = create_graph(requirements)
|
||||||
|
workers = for _ <- 1..5, do: {nil, 1}
|
||||||
|
tick(workers, nodes, graph)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,101 @@
|
||||||
|
Step T must be finished before step C can begin.
|
||||||
|
Step V must be finished before step C can begin.
|
||||||
|
Step Y must be finished before step H can begin.
|
||||||
|
Step R must be finished before step U can begin.
|
||||||
|
Step B must be finished before step J can begin.
|
||||||
|
Step Q must be finished before step O can begin.
|
||||||
|
Step W must be finished before step O can begin.
|
||||||
|
Step S must be finished before step X can begin.
|
||||||
|
Step I must be finished before step N can begin.
|
||||||
|
Step X must be finished before step H can begin.
|
||||||
|
Step M must be finished before step L can begin.
|
||||||
|
Step A must be finished before step F can begin.
|
||||||
|
Step G must be finished before step P can begin.
|
||||||
|
Step U must be finished before step E can begin.
|
||||||
|
Step Z must be finished before step E can begin.
|
||||||
|
Step H must be finished before step L can begin.
|
||||||
|
Step P must be finished before step C can begin.
|
||||||
|
Step K must be finished before step F can begin.
|
||||||
|
Step O must be finished before step C can begin.
|
||||||
|
Step C must be finished before step F can begin.
|
||||||
|
Step D must be finished before step L can begin.
|
||||||
|
Step L must be finished before step F can begin.
|
||||||
|
Step N must be finished before step E can begin.
|
||||||
|
Step J must be finished before step F can begin.
|
||||||
|
Step F must be finished before step E can begin.
|
||||||
|
Step I must be finished before step A can begin.
|
||||||
|
Step Z must be finished before step J can begin.
|
||||||
|
Step I must be finished before step P can begin.
|
||||||
|
Step T must be finished before step E can begin.
|
||||||
|
Step R must be finished before step F can begin.
|
||||||
|
Step U must be finished before step H can begin.
|
||||||
|
Step K must be finished before step E can begin.
|
||||||
|
Step D must be finished before step N can begin.
|
||||||
|
Step U must be finished before step C can begin.
|
||||||
|
Step D must be finished before step J can begin.
|
||||||
|
Step N must be finished before step F can begin.
|
||||||
|
Step C must be finished before step J can begin.
|
||||||
|
Step U must be finished before step J can begin.
|
||||||
|
Step A must be finished before step O can begin.
|
||||||
|
Step H must be finished before step N can begin.
|
||||||
|
Step P must be finished before step O can begin.
|
||||||
|
Step I must be finished before step E can begin.
|
||||||
|
Step G must be finished before step F can begin.
|
||||||
|
Step O must be finished before step J can begin.
|
||||||
|
Step Q must be finished before step F can begin.
|
||||||
|
Step G must be finished before step J can begin.
|
||||||
|
Step X must be finished before step E can begin.
|
||||||
|
Step S must be finished before step D can begin.
|
||||||
|
Step R must be finished before step P can begin.
|
||||||
|
Step K must be finished before step L can begin.
|
||||||
|
Step R must be finished before step Q can begin.
|
||||||
|
Step L must be finished before step N can begin.
|
||||||
|
Step Q must be finished before step C can begin.
|
||||||
|
Step C must be finished before step D can begin.
|
||||||
|
Step C must be finished before step N can begin.
|
||||||
|
Step O must be finished before step E can begin.
|
||||||
|
Step W must be finished before step F can begin.
|
||||||
|
Step K must be finished before step D can begin.
|
||||||
|
Step T must be finished before step H can begin.
|
||||||
|
Step M must be finished before step D can begin.
|
||||||
|
Step Y must be finished before step Z can begin.
|
||||||
|
Step J must be finished before step E can begin.
|
||||||
|
Step S must be finished before step F can begin.
|
||||||
|
Step G must be finished before step U can begin.
|
||||||
|
Step V must be finished before step S can begin.
|
||||||
|
Step Y must be finished before step F can begin.
|
||||||
|
Step G must be finished before step H can begin.
|
||||||
|
Step T must be finished before step Q can begin.
|
||||||
|
Step S must be finished before step U can begin.
|
||||||
|
Step V must be finished before step D can begin.
|
||||||
|
Step W must be finished before step M can begin.
|
||||||
|
Step M must be finished before step E can begin.
|
||||||
|
Step A must be finished before step H can begin.
|
||||||
|
Step B must be finished before step F can begin.
|
||||||
|
Step B must be finished before step N can begin.
|
||||||
|
Step D must be finished before step F can begin.
|
||||||
|
Step W must be finished before step K can begin.
|
||||||
|
Step P must be finished before step E can begin.
|
||||||
|
Step B must be finished before step X can begin.
|
||||||
|
Step Q must be finished before step U can begin.
|
||||||
|
Step Q must be finished before step X can begin.
|
||||||
|
Step X must be finished before step N can begin.
|
||||||
|
Step M must be finished before step Z can begin.
|
||||||
|
Step G must be finished before step Z can begin.
|
||||||
|
Step S must be finished before step G can begin.
|
||||||
|
Step P must be finished before step F can begin.
|
||||||
|
Step I must be finished before step O can begin.
|
||||||
|
Step R must be finished before step A can begin.
|
||||||
|
Step L must be finished before step J can begin.
|
||||||
|
Step B must be finished before step I can begin.
|
||||||
|
Step C must be finished before step E can begin.
|
||||||
|
Step B must be finished before step W can begin.
|
||||||
|
Step P must be finished before step N can begin.
|
||||||
|
Step H must be finished before step C can begin.
|
||||||
|
Step K must be finished before step J can begin.
|
||||||
|
Step Y must be finished before step M can begin.
|
||||||
|
Step Z must be finished before step P can begin.
|
||||||
|
Step I must be finished before step K can begin.
|
||||||
|
Step V must be finished before step E can begin.
|
||||||
|
Step Y must be finished before step P can begin.
|
||||||
|
Step T must be finished before step R can begin.
|
|
@ -0,0 +1,4 @@
|
||||||
|
defmodule Day7Test do
|
||||||
|
use ExUnit.Case
|
||||||
|
doctest Day7
|
||||||
|
end
|
Loading…
Reference in New Issue