this repo has no description
1<!-- livebook:{"persist_outputs":true} -->
2
3# Day 16
4
5```elixir
6Mix.install([:kino_aoc])
7```
8
9## Section
10
11<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"16","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
12
13```elixir
14{:ok, puzzle_input} =
15 KinoAOC.download_puzzle("2023", "16", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
16```
17
18<!-- livebook:{"output":true} -->
19
20```
21{:ok,
22 "\\\\.......\\.............../-........|......................-......../..................../......./....|........\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....................................../..\\....\\\\.............\\...................||/.../.../........\\.........\n............./..../....-...|........../-.............\\......................................\\/........-..-....\n.................\\\\...............|\\\\...........\\.........../......-.......-............\\..............-..-..\\\n...|..../..|../..|........./.../.-..............................\\.........-........................|.\\....||..\n......................./..|....-..............................-........................././../................\n../.\\.............//.\\.|..................-.....\\...........|..././............/...................." <> ...}
23```
24
25```elixir
26# puzzle_input =
27~S"""
28.|...\....
29|.-.\.....
30.....|-...
31........|.
32..........
33.........\
34..../.\\..
35.-.-/..|..
36.|....-|.\
37..//.|....
38"""
39```
40
41<!-- livebook:{"output":true} -->
42
43```
44".|...\\....\n|.-.\\.....\n.....|-...\n........|.\n..........\n.........\\\n..../.\\\\..\n.-.-/..|..\n.|....-|.\\\n..//.|....\n"
45```
46
47```elixir
48lines = String.split(puzzle_input, "\n", trim: true)
49
50map =
51 for {line, y} <- Enum.with_index(lines),
52 {char, x} <- line |> String.to_charlist() |> Enum.with_index(),
53 char not in ~c".",
54 into: %{},
55 do: {{y, x}, <<char>>}
56
57{height, width} = {byte_size(hd(lines)) - 1, length(lines) - 1}
58```
59
60<!-- livebook:{"output":true} -->
61
62```
63{109, 109}
64```
65
66```elixir
67defmodule Day16 do
68 defguard in_map(yx, hw) when elem(yx, 0) in 0..elem(hw, 0) and elem(yx, 1) in 0..elem(hw, 1)
69
70 def traverse(map, wh, start \\ {{0, 0}, :right}),
71 do: do_traverse(map, wh, start, _acc = MapSet.new(), _visited = MapSet.new())
72
73 defp do_traverse(map, hw, {xy, dir} = pos, acc, visited) when in_map(xy, hw) do
74 if pos not in visited do
75 acc = MapSet.put(acc, xy)
76
77 case Map.fetch(map, xy) do
78 :error ->
79 do_traverse(map, hw, next(xy, dir), acc, visited)
80
81 {:ok, "|"} when dir in ~w[up down]a ->
82 do_traverse(map, hw, next(xy, dir), acc, visited)
83
84 {:ok, "-"} when dir in ~w[left right]a ->
85 do_traverse(map, hw, next(xy, dir), acc, visited)
86
87 {:ok, mirror} when mirror in ~w[/ \\] ->
88 next = mirror(mirror, dir)
89 do_traverse(map, hw, next(xy, next), acc, MapSet.put(visited, pos))
90
91 {:ok, "|"} when dir in ~w[left right]a ->
92 # Add both sides to visited, as it will result in the same outcome
93 visited =
94 visited
95 |> MapSet.put({xy, :left})
96 |> MapSet.put({xy, :right})
97
98 {acc, visited} = do_traverse(map, hw, next(xy, :up), acc, visited)
99 do_traverse(map, hw, next(xy, :down), acc, visited)
100
101 {:ok, "-"} when dir in ~w[up down]a ->
102 # Add both sides to visited, as it will result in the same outcome
103 visited =
104 visited
105 |> MapSet.put({xy, :up})
106 |> MapSet.put({xy, :down})
107
108 {acc, visited} = do_traverse(map, hw, next(xy, :left), acc, visited)
109 do_traverse(map, hw, next(xy, :right), acc, visited)
110 end
111 else
112 {acc, visited}
113 end
114 end
115
116 defp do_traverse(_, _wh, _pos, acc, visited) do
117 {acc, visited}
118 end
119
120 defp mirror("/", :up), do: :right
121 defp mirror("/", :left), do: :down
122 defp mirror("/", :down), do: :left
123 defp mirror("/", :right), do: :up
124
125 defp mirror("\\", :up), do: :left
126 defp mirror("\\", :left), do: :up
127 defp mirror("\\", :down), do: :right
128 defp mirror("\\", :right), do: :down
129
130 defp next({y, x}, :up), do: {{y - 1, x}, :up}
131 defp next({y, x}, :left), do: {{y, x - 1}, :left}
132 defp next({y, x}, :down), do: {{y + 1, x}, :down}
133 defp next({y, x}, :right), do: {{y, x + 1}, :right}
134end
135```
136
137<!-- livebook:{"output":true} -->
138
139```
140{:module, Day16, <<70, 79, 82, 49, 0, 0, 28, ...>>, {:next, 2}}
141```
142
143## Part 1
144
145```elixir
146{path, _} = Day16.traverse(map, {height, width})
147
148MapSet.size(path)
149```
150
151<!-- livebook:{"output":true} -->
152
153```
1547242
155```
156
157## Part 2
158
159```elixir
160start_points =
161 Enum.concat([
162 Enum.flat_map(0..height, &[{{&1, 0}, :right}, {{&1, width}, :left}]),
163 Enum.flat_map(0..width, &[{{0, &1}, :down}, {{height, &1}, :up}])
164 ])
165
166start_points
167|> Task.async_stream(&Day16.traverse(map, {height, width}, &1))
168|> Stream.map(fn {:ok, {path, _}} -> MapSet.size(path) end)
169|> Enum.max()
170```
171
172<!-- livebook:{"output":true} -->
173
174```
1757572
176```
177
178<!-- livebook:{"offset":8394,"stamp":{"token":"XCP.G2qkGI0iiEpXKpxgmF3X_dOzQWYnfJes3P9XQazzqVafzbVljgd42sRxbC_RC5Nc9-rrcx45UodmXf17HwB9X_4sZz6up_iLXNZDUxXQ0eGyvZkk_NcBMt5FRaALMHBiHw","version":2}} -->