Hey there, amazing community! Ukrainian Erlanger is here , and it’s a beautiful Sunday. Today unfolds as Day 10 in the exhilarating adventure of Advent of Code, bringing with it a brand-new puzzle to unravel. As you embark on this coding escapade, feel free to share your ingenious solutions in the comments below. Let’s celebrate the spirit of learning and collaboration. Wishing you all a relaxing Sunday filled with coding delights. Happy coding, folks!
3 Likes
I had to take a hint for part 2.
2 Likes
My day 10 solution, definitely spent too much time on that one, I’m sure there are much more elegant solutions:
defmodule Aoc.Ten do
def parse(string) do
string
|> String.split("\n", trim: true)
|> Enum.map(&String.to_charlist/1)
|> load()
end
def load(data) do
for {line, y} <- Enum.with_index(data), {i, x} <- Enum.with_index(line), i != ?., into: %{} do
{{y, x}, i}
end
end
def part_one(map) do
map
|> walk_loop()
|> Map.values()
|> Enum.max()
end
def part_two(map) do
loop =
map
|> walk_loop()
|> Map.keys()
|> MapSet.new()
map
|> inside_loop(loop)
|> Enum.count()
end
def walk_loop(map) do
map
|> Enum.find(map, fn {_, v} -> v == ?S end)
|> walk_loop(map)
end
def walk_loop({c, _}, map) do
walk_loop([c], map, 1, %{c => 0})
end
def walk_loop([], _, _, seen), do: seen
def walk_loop(coords, map, n, seen) do
directions =
for c <- coords,
{dir, x} <- around(c),
Map.has_key?(map, x),
not Map.has_key?(seen, x),
is_connected(map[c], {dir, x}, map) do
x
end
new_seen = Enum.reduce(directions, seen, fn x, acc -> Map.put(acc, x, n) end)
walk_loop(directions, map, n + 1, new_seen)
end
@nav %{
up: ~c"S|7F",
down: ~c"S|LJ",
left: ~c"S-LF",
right: ~c"S-7J"
}
@dirs %{
?| => [:up, :down],
?- => [:left, :right],
?L => [:up, :right],
?J => [:up, :left],
?7 => [:down, :left],
?F => [:down, :right],
?S => [:up, :down, :left, :right]
}
def is_connected(v0, {dir, c}, map) do
v = Map.get(map, c)
Enum.any?(@dirs[v0], fn d -> d == dir and v in @nav[dir] end)
end
def around({y, x}) do
[{:up, {y - 1, x}}, {:down, {y + 1, x}}, {:left, {y, x - 1}}, {:right, {y, x + 1}}]
end
def inside_loop(map, loop) do
{ys, xs} = map |> Map.keys() |> Enum.max()
for y <- 0..ys, x <- 0..xs, {y, x} not in loop, is_inside_loop({y, x}, map, loop) do
{y, x}
end
end
def is_inside_loop({y, x}, map, loop) do
Enum.reduce((y - 1)..0, false, fn y, acc ->
if {y, x} in loop and map[{y, x}] in ~c"-LF" do
not acc
else
acc
end
end)
end
end
input = File.read!("priv/10.txt") |> Aoc.Ten.parse()
input |> Aoc.Ten.part_one() |> IO.inspect(label: "part 1")
input |> Aoc.Ten.part_two() |> IO.inspect(label: "part 2")
1 Like