Day 16
This commit is contained in:
71
lib/day16.ex
Normal file
71
lib/day16.ex
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
defmodule Aoc2023.Day16 do
|
||||||
|
use Aoc2023
|
||||||
|
|
||||||
|
defp emissions(char, dir) do
|
||||||
|
case {char, dir} do
|
||||||
|
{?., dir} -> [dir]
|
||||||
|
{?-, {0, dir}} -> [{0, dir}]
|
||||||
|
{?-, {_, 0}} -> [{0, -1}, {0, 1}]
|
||||||
|
{?|, {dir, 0}} -> [{dir, 0}]
|
||||||
|
{?|, {0, _}} -> [{-1, 0}, {1, 0}]
|
||||||
|
{?/, {dir, 0}} -> [{0, -dir}]
|
||||||
|
{?/, {0, dir}} -> [{-dir, 0}]
|
||||||
|
{?\\, {dir, 0}} -> [{0, dir}]
|
||||||
|
{?\\, {0, dir}} -> [{dir, 0}]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp add_vec({y, x}, {y_, x_}) do
|
||||||
|
{y + y_, x + x_}
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse(input) do
|
||||||
|
input
|
||||||
|
|> lines
|
||||||
|
|> Enum.map(&String.to_charlist/1)
|
||||||
|
|> Enum.with_index()
|
||||||
|
|> Enum.flat_map(fn {row, y} ->
|
||||||
|
row |> Enum.with_index() |> Enum.map(fn {c, x} -> {{y, x}, c} end)
|
||||||
|
end)
|
||||||
|
|> Enum.into(%{})
|
||||||
|
end
|
||||||
|
|
||||||
|
defp run(input, heads) do
|
||||||
|
loop = fn recur, energized, heads ->
|
||||||
|
energized_ = MapSet.union(energized, heads |> MapSet.new())
|
||||||
|
|
||||||
|
heads_ =
|
||||||
|
heads
|
||||||
|
|> Enum.flat_map(fn {coord, dir} ->
|
||||||
|
char = Map.get(input, coord)
|
||||||
|
|
||||||
|
if char,
|
||||||
|
do:
|
||||||
|
emissions(char, dir)
|
||||||
|
|> Enum.map(&{add_vec(coord, &1), &1})
|
||||||
|
|> Enum.reject(&MapSet.member?(energized_, &1))
|
||||||
|
|> Enum.filter(&Map.has_key?(input, elem(&1, 0))),
|
||||||
|
else: []
|
||||||
|
end)
|
||||||
|
|
||||||
|
if length(heads_) > 0, do: recur.(recur, energized_, heads_), else: energized_
|
||||||
|
end
|
||||||
|
|
||||||
|
loop.(loop, MapSet.new(), heads) |> Enum.map(pipe(elem(0))) |> MapSet.new() |> MapSet.size()
|
||||||
|
end
|
||||||
|
|
||||||
|
def part1(input) do
|
||||||
|
run(input, [{{0, 0}, {0, 1}}])
|
||||||
|
end
|
||||||
|
|
||||||
|
def part2(input) do
|
||||||
|
{my, mx} = input |> Enum.map(pipe(elem(0))) |> Enum.max()
|
||||||
|
|
||||||
|
[
|
||||||
|
0..my |> Enum.map(&{{&1, 0}, {0, 1}}),
|
||||||
|
0..my |> Enum.map(&{{&1, mx}, {0, -1}}),
|
||||||
|
0..mx |> Enum.map(&{{0, &1}, {1, 0}}),
|
||||||
|
0..mx |> Enum.map(&{{my, &1}, {-1, 0}})
|
||||||
|
] |> Enum.concat |> Enum.map(&run(input, [&1])) |> Enum.max
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -17,6 +17,7 @@ defmodule Mix.Tasks.Aoc do
|
|||||||
defp module(13), do: Aoc2023.Day13
|
defp module(13), do: Aoc2023.Day13
|
||||||
defp module(14), do: Aoc2023.Day14
|
defp module(14), do: Aoc2023.Day14
|
||||||
defp module(15), do: Aoc2023.Day15
|
defp module(15), do: Aoc2023.Day15
|
||||||
|
defp module(16), do: Aoc2023.Day16
|
||||||
# [MODULE INSERTION POINT]
|
# [MODULE INSERTION POINT]
|
||||||
|
|
||||||
defp base_dir(), do: System.get_env("AOC_BASE")
|
defp base_dir(), do: System.get_env("AOC_BASE")
|
||||||
|
|||||||
10
tests/day16/1
Normal file
10
tests/day16/1
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
.|...\....
|
||||||
|
|.-.\.....
|
||||||
|
.....|-...
|
||||||
|
........|.
|
||||||
|
..........
|
||||||
|
.........\
|
||||||
|
..../.\\..
|
||||||
|
.-.-/..|..
|
||||||
|
.|....-|.\
|
||||||
|
..//.|....
|
||||||
1
tests/day16/1.1
Normal file
1
tests/day16/1.1
Normal file
@@ -0,0 +1 @@
|
|||||||
|
46
|
||||||
1
tests/day16/1.2
Normal file
1
tests/day16/1.2
Normal file
@@ -0,0 +1 @@
|
|||||||
|
51
|
||||||
Reference in New Issue
Block a user