Day 06
Mix.install([:kino_aoc, :arrays])
Section
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2024", "6", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
{:ok,
"...#..................#...................#......................#..............................#.............................#...\n....#.......................#........#.#..............##...........#.....#..........#..........................#..................\n.............#........................................................................#.........#.#..#..#..........#..............\n..........#.......#..........#..................#........##...................#..............#....................................\n....................#..........................................................#..#.....................................#.........\n....#............................#..............................................#.....................#..........##....#..........\n.......#.............#......................................................................#.............#.........#.............\n....###......................#....#...........#.....#................................#..........................#.................\n..........#..#...........#..#........................................................#.....#...........#................#.........\n..#....#......#....#....#...................................................................#.....................................\n....................#............#............................................#......#....#...............................#.......\n..........#.......#.........#.......#.............................................................................................\n.......#...#.......................................#...................#..........................................................\n.......#........#............................#.....#.......#..............................................#..................#...#\n.....................#.................................#................#...#...............#.....#.#..........................#..\n.....#..........................................#......................#.............##..............................#........#...\n.....#......#.........................#..........................#..........................................................#..#..\n.#......#.............#......#.................................................#.....#...................##......#................\n.............................................................................##...................................................\n........................................#.......................................#........#.............................#.#.......#\n...........#.....................................#.............................#......#......#..#....................#..#.........\n.............................................#.......................#..................##....#.....#.............................\n........................#..............................................................#..........................................\n#..............#.........................#........#...#...............#..............#..................#....................##...\n...#...#.............................#.......#................................................#........................#....#.....\n.....#.........................#..#.......................#..........#.....................#..................#.#.....#...........\n..................#........#..#.......#...................................................................................#....#..\n..#...#...............................................#.#..#........................................................#....#......#.\n...............#...............#..........................#............................#..........#.............#.................\n............#.....#........#.........................................................#........#........#.....#........#......#....\n............................#.........#....#........#.....#...#.............#.................................#...................\n........#..................#....#.." <> ...}
map =
puzzle_input
|> String.split("\n", trim: true)
|> Enum.with_index()
|> Enum.flat_map(fn {row, y} ->
row
|> String.to_charlist()
|> Enum.with_index()
|> Enum.map(fn {v, x} -> {{y, x}, v} end)
end)
|> Map.new()
%{
{18, 103} => 46,
{76, 13} => 46,
{61, 121} => 46,
{37, 47} => 46,
{65, 63} => 46,
{77, 129} => 46,
{120, 47} => 46,
{38, 2} => 46,
{1, 26} => 46,
{116, 69} => 46,
{124, 56} => 46,
{83, 76} => 46,
{117, 125} => 46,
{32, 15} => 46,
{103, 106} => 46,
{30, 113} => 46,
{123, 104} => 46,
{124, 60} => 46,
{89, 14} => 46,
{35, 30} => 46,
{37, 53} => 46,
{4, 5} => 46,
{8, 50} => 46,
{78, 98} => 46,
{101, 62} => 46,
{95, 56} => 46,
{74, 12} => 46,
{102, 74} => 46,
{11, 39} => 46,
{65, 43} => 46,
{22, 38} => 46,
{14, 86} => 46,
{49, 117} => 46,
{20, 41} => 46,
{29, 25} => 46,
{86, 10} => 46,
{83, 36} => 46,
{29, 26} => 46,
{47, 27} => 46,
{4, 81} => 46,
{31, 42} => 46,
{9, 34} => 46,
{13, 124} => 46,
{90, 0} => 46,
{14, 122} => 46,
{120, 42} => 46,
{121, 77} => 46,
{103, 39} => 46,
{102, ...} => 46,
{...} => 46,
...
}
{start_pos, _} = start = Enum.find(map, fn {_pos, v} -> v in ~c'^>v<' end)
map = Map.replace(map, start_pos, ?.)
start
{{93, 71}, 94}
defmodule Guard do
def walk(map, start),
do: walk(map, start, MapSet.new())
defp walk(map, {pos, dir} = curr, visited) do
if curr in visited do
:loop
else
visited = MapSet.put(visited, curr)
case Map.fetch(map, next(pos, dir)) do
{:ok, ?#} ->
walk(map, {pos, turn(dir)}, visited)
{:ok, ?.} ->
walk(map, {next(pos, dir), dir}, visited)
:error ->
MapSet.new(visited, fn {pos, _} -> pos end)
end
end
end
defp next({y, x}, ?^), do: {y - 1, x}
defp next({y, x}, ?>), do: {y, x + 1}
defp next({y, x}, ?v), do: {y + 1, x}
defp next({y, x}, ?<), do: {y, x - 1}
defp turn(?^), do: ?>
defp turn(?>), do: ?v
defp turn(?v), do: ?<
defp turn(?<), do: ?^
end
{:module, Guard, <<70, 79, 82, 49, 0, 0, 12, ...>>, {:turn, 1}}
Part 1
orig_path = Guard.walk(map, start)
MapSet.size(orig_path)
4433
Part 2
orig_path
|> MapSet.delete(start_pos)
|> Task.async_stream(fn point ->
map
|> Map.put(point, ?#)
|> Guard.walk(start)
|> Kernel.==(:loop)
end, ordered: false)
|> Enum.count(& &1)
4432