Day 10
Section
example = """
89010123
78121874
87430965
96549874
45678903
32019012
01329801
10456732
"""
defmodule Day10 do
def get_map(input) do
for {row, y} <- input |> String.split("\n", trim: true) |> Enum.with_index(),
{h, x} <- row |> String.split("", trim: true) |> Enum.with_index(),
into: %{} do
{{x, y}, String.to_integer(h)}
end
end
def get_starts(input) do
for {row, y} <- input |> String.split("\n", trim: true) |> Enum.with_index(),
{"0", x} <- row |> String.split("", trim: true) |> Enum.with_index() do
{x, y}
end
end
def solve(input, part) do
map = get_map(input)
starts = get_starts(input)
starts
|> Enum.map(fn {x, y} ->
move(x, y, 0, map, [])
|> List.flatten()
|> Enum.filter(& &1)
|> Enum.uniq_by(fn result ->
case part do
:part1 -> result.finished_at
:part2 -> result
end
end)
|> length()
end)
|> Enum.sum()
end
def move(x, y, h, map, path) do
for {nx, ny} <- [{x, y + 1}, {x, y - 1}, {x + 1, y}, {x - 1, y}] do
nh = Map.get(map, {nx, ny})
cond do
is_nil(nh) ->
nil
nh == 9 && nh - h == 1 ->
%{finished_at: {nx, ny}, path: [{nx, ny, nh} | path]}
nh - h == 1 ->
move(nx, ny, nh, map, [{nx, ny, nh} | path])
true ->
nil
end
end
end
end
Day10.solve(example, :part1)
Day10.solve(example, :part2)