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!
3 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)
|> load()
end
def load(data) do
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
input = File.read!("priv/16.txt") |> Aoc.Sixteen.parse()
input |> Aoc.Sixteen.part_one() |> IO.inspect(label: "part 1")
input |> Aoc.Sixteen.part_two() |> IO.inspect(label: "part 2")
1 Like