# Advent of Code 2023 - Day 10

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!

2 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)
end

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