2024 Day 6 part 2

This commit is contained in:
Adam Millerchip 2024-12-29 23:19:00 +09:00
parent 217e04c12b
commit a780d279c0

View file

@ -2,6 +2,7 @@
defmodule Patrol do defmodule Patrol do
defstruct obstacles: MapSet.new(), defstruct obstacles: MapSet.new(),
visited: MapSet.new(), visited: MapSet.new(),
path: MapSet.new(),
x: 0, x: 0,
y: 0, y: 0,
max_x: nil, max_x: nil,
@ -11,20 +12,32 @@ defmodule Patrol do
end end
defmodule Day6 do defmodule Day6 do
def part1(%Patrol{} = patrol) when patrol.x == patrol.max_x or patrol.y == patrol.max_y do def part1(patrol), do: MapSet.size(patrol(patrol).visited)
MapSet.size(patrol.visited)
def patrol(%Patrol{} = patrol) when patrol.x in [-1, patrol.max_x] or patrol.y in [-1, patrol.max_y] do
patrol
end end
def part1(%Patrol{} = patrol) do def patrol(%Patrol{} = patrol) do
next_x = patrol.x + patrol.dir_x next_x = patrol.x + patrol.dir_x
next_y = patrol.y + patrol.dir_y next_y = patrol.y + patrol.dir_y
if MapSet.member?(patrol.obstacles, {next_x, next_y}) do patrol =
{dir_x, dir_y} = turn_right(patrol.dir_x, patrol.dir_y) if MapSet.member?(patrol.obstacles, {next_x, next_y}) do
part1(%Patrol{patrol | dir_x: dir_x, dir_y: dir_y}) {dir_x, dir_y} = turn_right(patrol.dir_x, patrol.dir_y)
%Patrol{patrol | dir_x: dir_x, dir_y: dir_y}
else
visited = MapSet.put(patrol.visited, {patrol.x, patrol.y})
%Patrol{patrol | x: next_x, y: next_y, visited: visited}
end
next_path = {patrol.x, patrol.y, patrol.dir_x, patrol.dir_y}
if MapSet.member?(patrol.path, next_path) do
:loop
else else
visited = MapSet.put(patrol.visited, {patrol.x, patrol.y}) patrol = %Patrol{patrol | path: MapSet.put(patrol.path, next_path)}
part1(%Patrol{patrol | x: next_x, y: next_y, visited: visited}) patrol(patrol)
end end
end end
@ -33,9 +46,20 @@ defmodule Day6 do
def turn_right(0, 1), do: {-1, 0} def turn_right(0, 1), do: {-1, 0}
def turn_right(-1, 0), do: {0, -1} def turn_right(-1, 0), do: {0, -1}
def part2(_input) do def part2(patrol) do
# hmmmmmmm probably need completely different solution completed_patrol = patrol(patrol)
:ok
candidate_obstructions =
Enum.reduce(completed_patrol.visited, MapSet.new(), fn {x, y}, candidate_obstructions ->
Enum.into([{x - 1, y}, {x + 1, y}, {x, y - 1}, {x, y + 1}], candidate_obstructions)
end)
Enum.count(candidate_obstructions, fn {x, y} ->
new_obstacles = MapSet.put(patrol.obstacles, {x, y})
new_patrol = %Patrol{patrol | obstacles: new_obstacles}
patrol(new_patrol) == :loop
end)
end end
def input do def input do