Day 15
Setup
Mix.install([
{:kino, "~> 0.4.1"},
{:libgraph, "~> 0.7"}
])
input = Kino.Input.textarea("Please provide your input: ")
input =
input
|> Kino.Input.read()
|> String.split("\n")
defmodule AOC.DayFifteen do
def solve(grid) do
graph = Graph.new()
graph =
Enum.reduce(grid, graph, fn {{x, y}, _weight}, acc ->
edge_1 = grid[{x, y + 1}]
edge_2 = grid[{x + 1, y}]
cond do
nil != edge_1 and nil != edge_2 ->
Graph.add_edges(
acc,
[
Graph.Edge.new({x, y}, {x, y + 1}, weight: edge_1),
Graph.Edge.new({x, y}, {x + 1, y}, weight: edge_2)
]
)
nil != edge_1 ->
Graph.add_edge(
acc,
Graph.Edge.new({x, y}, {x, y + 1}, weight: edge_1)
)
nil != edge_2 ->
Graph.add_edge(
acc,
Graph.Edge.new({x, y}, {x + 1, y}, weight: edge_2)
)
true ->
acc
end
end)
{{min, _}, {max, _}} = Enum.min_max(grid)
[_head | tail] =
graph
|> Graph.dijkstra(min, max)
tail
|> Enum.reduce(0, fn point, sum -> sum + grid[point] end)
end
def inc(x, n) do
cond do
n + x > 9 -> n + x - 9
:else -> n + x
end
end
end
Part 1
grid =
for {line, row} <- Enum.with_index(input),
{value, col} <- Enum.with_index(String.to_charlist(line)),
into: %{} do
{{col, row}, value - ?0}
end
AOC.DayFifteen.solve(grid)
{_, {{max, _}, _}} = Enum.min_max(grid)
max = max + 1
grid =
grid
|> Enum.reduce(%{}, fn {{x, y}, cost}, acc ->
Map.merge(acc, %{
{x, y} => cost,
{x + max, y} => AOC.DayFifteen.inc(cost, 1),
{x + max * 2, y} => AOC.DayFifteen.inc(cost, 2),
{x + max * 3, y} => AOC.DayFifteen.inc(cost, 3),
{x + max * 4, y} => AOC.DayFifteen.inc(cost, 4)
})
end)
|> Enum.reduce(%{}, fn {{x, y}, cost}, acc ->
Map.merge(acc, %{
{x, y} => cost,
{x, y + max} => AOC.DayFifteen.inc(cost, 1),
{x, y + max * 2} => AOC.DayFifteen.inc(cost, 2),
{x, y + max * 3} => AOC.DayFifteen.inc(cost, 3),
{x, y + max * 4} => AOC.DayFifteen.inc(cost, 4)
})
end)
AOC.DayFifteen.solve(grid)