# Advent of Code 2023 - Day 16

Hey, coding wizards! Ukrainian Erlanger checking in on this splendid Saturday . It’s Day 16 in our captivating exploration of Advent of Code, and a fresh puzzle beckons your coding ingenuity. Dive into the challenge, conquer the complexities, and, as always, share your brilliant solutions in the comments below. Let’s make this Saturday a coding triumph and keep the collaborative spirit alive! Happy coding, everyone!

2 Likes
2 Likes

My day 16 solution:

``````defmodule Aoc.Sixteen do
def parse(string) do
string
|> String.split("\n", trim: true)
|> Enum.map(fn line ->
line
|> String.graphemes()
end)
end

for {line, y} <- Enum.with_index(data, 1), {i, x} <- Enum.with_index(line, 1), into: %{} do
{{x, y}, i}
end
end

def part_one(input) do
input
|> walk({{0, 1}, :r})
end

def part_two(input) do
{max_x, max_y} = input |> Map.keys() |> Enum.max()

vert = for x <- 1..100, do: [{{x, 0}, :d}, {{x, max_x}, :u}]
horz = for y <- 1..100, do: [{{0, y}, :r}, {{max_y, y}, :l}]

(vert ++ horz)
|> Enum.concat()
|> Enum.map(&walk(input, &1))
|> Enum.max()
end

defp walk(map, start) do
start
|> next_directions(map)
|> walk(map, MapSet.new())
end

defp walk([], _map, seen) do
seen |> Enum.unzip() |> elem(0) |> Enum.uniq() |> Enum.count()
end

defp walk([next | rest], map, seen) do
{new_seen, new_directions} =
if MapSet.member?(seen, next) do
{seen, rest}
else
new_seen = MapSet.put(seen, next)
{new_seen, next_directions(next, map) ++ rest}
end
walk(new_directions, map, new_seen)
end

defp next_directions({{x, y}, dir}, map) do
nc =
case dir do
:u -> {x, y - 1}
:d -> {x, y + 1}
:l -> {x - 1, y}
:r -> {x + 1, y}
end

case Map.get(map, nc) do
nil ->
[]

"." ->
[{nc, dir}]

"/" ->
case dir do
:u -> [{nc, :r}]
:d -> [{nc, :l}]
:l -> [{nc, :d}]
:r -> [{nc, :u}]
end

"\\" ->
case dir do
:u -> [{nc, :l}]
:d -> [{nc, :r}]
:l -> [{nc, :u}]
:r -> [{nc, :d}]
end

"|" ->
case dir do
:u -> [{nc, :u}]
:d -> [{nc, :d}]
:l -> [{nc, :u}, {nc, :d}]
:r -> [{nc, :u}, {nc, :d}]
end

"-" ->
case dir do
:u -> [{nc, :l}, {nc, :r}]
:d -> [{nc, :l}, {nc, :r}]
:l -> [{nc, :l}]
:r -> [{nc, :r}]
end
end
end
end