Advent of Code 2024 - Day 10
Mix.install([
{:kino, github: "livebook-dev/kino"},
{:libgraph, "~> 0.16.0"},
])
kino_input = Kino.Input.textarea("Please paste your input file: ")
Part 1
input = Kino.Input.read(kino_input)
input
|> String.split("\n", trim: true)
|> Enum.with_index()
|> Enum.reduce(%{}, fn {row, row_index}, map ->
row
|> String.graphemes()
|> Enum.with_index()
|> Enum.reduce(map, fn {char, column_index}, acc ->
case Integer.parse(char) do
{digit, ""} ->
Map.put(acc, {column_index, row_index}, digit)
_ -> acc
end
end)
end)
|> then(fn digit_positions ->
graph =
digit_positions
|> Enum.reduce(Graph.new(type: :directed), fn {coords, _}, g ->
g |> Graph.add_vertex(coords)
end)
graph =
Enum.reduce(digit_positions, graph, fn {{x1, y1} = coords1, n}, g ->
[{x1, y1 - 1}, {x1, y1 + 1}, {x1 - 1, y1}, {x1 + 1, y1}]
|> Enum.reduce(g, fn coords2, acc ->
if Map.get(digit_positions, coords2) == n + 1 do
Graph.add_edge(acc, coords1, coords2)
else
acc
end
end)
end)
positions_0 =
digit_positions
|> Enum.filter(&elem(&1, 1) == 0)
|> Enum.map(&elem(&1, 0))
positions_9 =
digit_positions
|> Enum.filter(&elem(&1, 1) == 9)
|> Enum.map(&elem(&1, 0))
for start <- positions_0,
dest <- positions_9,
Graph.get_paths(graph, start, dest) != [],
reduce: 0,
do: (sum -> sum + 1)
end)
Part 2
input = Kino.Input.read(kino_input)
input
|> String.split("\n", trim: true)
|> Enum.with_index()
|> Enum.reduce(%{}, fn {row, row_index}, map ->
row
|> String.graphemes()
|> Enum.with_index()
|> Enum.reduce(map, fn {char, column_index}, acc ->
case Integer.parse(char) do
{digit, ""} ->
Map.put(acc, {column_index, row_index}, digit)
_ -> acc
end
end)
end)
|> then(fn digit_positions ->
graph =
digit_positions
|> Enum.reduce(Graph.new(type: :directed), fn {coords, _}, g ->
g |> Graph.add_vertex(coords)
end)
graph =
Enum.reduce(digit_positions, graph, fn {{x1, y1} = coords1, n}, g ->
[{x1, y1 - 1}, {x1, y1 + 1}, {x1 - 1, y1}, {x1 + 1, y1}]
|> Enum.reduce(g, fn coords2, acc ->
if Map.get(digit_positions, coords2) == n + 1 do
Graph.add_edge(acc, coords1, coords2)
else
acc
end
end)
end)
positions_0 =
digit_positions
|> Enum.filter(&elem(&1, 1) == 0)
|> Enum.map(&elem(&1, 0))
positions_9 =
digit_positions
|> Enum.filter(&elem(&1, 1) == 9)
|> Enum.map(&elem(&1, 0))
for start <- positions_0,
dest <- positions_9,
paths = Graph.get_paths(graph, start, dest),
reduce: 0,
do: (sum -> sum + length(paths))
end)