Advent of Code 2021 day 12
Setup
Mix.install([
{:kino, "~> 0.4.1"}
])
input = Kino.Input.textarea("Paste your input here:")
edges =
input
|> Kino.Input.read()
|> String.split("\n", trim: true)
|> Enum.reduce(%{}, fn line, acc ->
[left, right] = String.split(line, "-")
acc = Map.update(acc, left, [right], &[right | &1])
if left == "start" or right == "end" do
acc
else
Map.update(acc, right, [left], &[left | &1])
end
end)
Part 1
defmodule Day12 do
def walk(edges) do
walk(edges["start"], ["start"], edges, MapSet.new(), [])
end
defp walk(["end" | caves], walked, edges, seen, pathes) do
valid_path = Enum.reverse(["end" | walked]) |> Enum.join("-")
walk(caves, walked, edges, seen, [valid_path | pathes])
end
defp walk([cave | caves], walked, edges, seen, pathes) do
pathes =
cond do
cave == "start" or cave in seen ->
pathes
lowercased?(cave) ->
walk(edges[cave], [cave | walked], edges, MapSet.put(seen, cave), pathes)
true ->
walk(edges[cave], [cave | walked], edges, seen, pathes)
end
walk(caves, walked, edges, seen, pathes)
end
defp walk([], _walked, _edges, _seen, pathes), do: pathes
defp lowercased?(cave), do: String.downcase(cave, :ascii) == cave
end
Day12.walk(edges)
|> IO.inspect()
|> Enum.count()
Part 2
defmodule Day12Part2 do
def twice(edges) do
walk(edges["start"], ["start"], edges, MapSet.new(), false, [])
end
defp walk(["end" | caves], walked, edges, seen, once?, pathes) do
valid_path = Enum.reverse(["end" | walked]) |> Enum.join("-")
walk(caves, walked, edges, seen, once?, [valid_path | pathes])
end
defp walk([cave | caves], walked, edges, seen, once?, pathes) do
pathes =
cond do
cave == "start" or (cave in seen and once?) ->
pathes
cave in seen ->
walk(edges[cave], [cave | walked], edges, MapSet.put(seen, cave), true, pathes)
lowercased?(cave) ->
walk(edges[cave], [cave | walked], edges, MapSet.put(seen, cave), once?, pathes)
true ->
walk(edges[cave], [cave | walked], edges, seen, once?, pathes)
end
walk(caves, [cave | walked], edges, seen, once?, pathes)
end
defp walk([], _walked, _edges, _seen, _once?, pathes), do: pathes
defp lowercased?(cave), do: String.downcase(cave, :ascii) == cave
end
Day12Part2.twice(edges)
|> IO.inspect()
|> Enum.count()