+73
2023/day08.livemd
+73
2023/day08.livemd
···
1
+
# Day 08
2
+
3
+
```elixir
4
+
Mix.install([:kino_aoc])
5
+
```
6
+
7
+
## Section
8
+
9
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"8","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
10
+
11
+
```elixir
12
+
{:ok, puzzle_input} =
13
+
KinoAOC.download_puzzle("2023", "8", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
14
+
```
15
+
16
+
```elixir
17
+
# puzzle_input =
18
+
"""
19
+
LR
20
+
21
+
11A = (11B, XXX)
22
+
11B = (XXX, 11Z)
23
+
11Z = (11B, XXX)
24
+
22A = (22B, XXX)
25
+
22B = (22C, 22C)
26
+
22C = (22Z, 22Z)
27
+
22Z = (22B, 22B)
28
+
XXX = (XXX, XXX)
29
+
"""
30
+
```
31
+
32
+
```elixir
33
+
defmodule Day08 do
34
+
def find_path(instructions, pos, map) do
35
+
Enum.reduce_while(instructions, pos, fn
36
+
{_, idx}, <<_, _, ?Z>> -> {:halt, idx}
37
+
{step, _}, pos -> {:cont, elem(Map.fetch!(map, pos), step)}
38
+
end)
39
+
end
40
+
end
41
+
42
+
[instructions | rest] =
43
+
String.split(puzzle_input, "\n", trim: true)
44
+
45
+
instructions =
46
+
Stream.cycle(for <<c <- instructions>>, do: if(c == ?L, do: 0, else: 1))
47
+
|> Stream.with_index()
48
+
49
+
map =
50
+
Map.new(rest, fn
51
+
<<src::binary-3>> <> " = (" <> <<left::binary-3>> <> ", " <> <<right::binary-3>> <> ")" ->
52
+
{src, {left, right}}
53
+
end)
54
+
```
55
+
56
+
## Part 1
57
+
58
+
```elixir
59
+
Day08.find_path(instructions, "AAA", map)
60
+
```
61
+
62
+
## Part 2
63
+
64
+
```elixir
65
+
starts = map |> Map.keys() |> Enum.filter(&String.ends_with?(&1, "A"))
66
+
67
+
Task.async_stream(starts, &Day08.find_path(instructions, &1, map), ordered: false)
68
+
|> Enum.reduce(1, fn {:ok, a}, b ->
69
+
div(a * b, Integer.gcd(a, b))
70
+
end)
71
+
```
72
+
73
+
<!-- livebook:{"offset":1485,"stamp":{"token":"XCP.dP8RakyYvjO2Dt2LfELbhGu7h_AlwhvgijUPOM_xnTL158Wj_I2mpQbyuTUJEnrHmVyOVnplBQcB1UHSBWM-ogSxBCmlsFU8DVr00oukCY_wP9T2YAIinkNIn_0CtZ7tkg","version":2}} -->
+188
2023/day09.livemd
+188
2023/day09.livemd
···
1
+
<!-- livebook:{"persist_outputs":true} -->
2
+
3
+
# Day 09
4
+
5
+
```elixir
6
+
Mix.install([:kino_aoc])
7
+
```
8
+
9
+
## Section
10
+
11
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"9","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", "9", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
16
+
```
17
+
18
+
<!-- livebook:{"output":true} -->
19
+
20
+
```
21
+
{:ok,
22
+
"27 49 92 176 327 586 1039 1879 3511 6711 12850 24194 44291 78456 134365 222769 358339 560653 855336 1275364 1862543\n15 25 36 57 117 286 706 1643 3584 7420 14791 28745 55012 104457 197703 373565 703877 1318603 2446886 4482001 8081143\n2 -1 -1 5 35 140 429 1101 2482 5067 9586 17171 29829 51664 91688 169675 327410 648943 1295161 2560233 4960367\n17 40 75 124 195 314 553 1083 2269 4852 10332 21799 45683 95258 197352 404834 819561 1634448 3210609 6218318 11892083\n12 28 47 77 148 320 690 1410 2740 5170 9648 17942 33138 60228 106667 182671 300884 474856 715541 1024739 1384064\n23 34 56 98 179 335 630 1192 2323 4773 10330 22981 51089 111404 236460 488303 984007 1942732 3771076 7214380 13617999\n-3 9 34 76 147 268 465 760 1157 1623 2064 2296 2011 738 -2201 -7740 -17123 -31963 -54306 -86700 -132269\n2 5 10 28 85 240 617 1451 3148 6359 12068 21694 37207 61258 97323 149861 224486 328153 469358 658352 907369\n2 8 19 26 30 54 164 525 1536 4108 10175 23584 51670 108250 219765 438340 869318 1727304 3445143 6876026 13651774\n-7 -3 9 42 129 327 726 1476 2850 5366 9996 18495 33888 61158 108183 186975 315279 518595 832691 1306680 2006739\n14 15 24 47 93 174 306 517 868 1493 2664 4887 9035 16524 29538 51309 86458 141403 224840 348303 526809\n-4 10 50 125 241 410 669 1105 1873 3186 5269 8334 12802 20376 37376 83418 211850 554706 1416484 3461131 8070127\n15 39 76 141 268 519 996 1856 3329 5739 9528 15283 23766 35947 53040 76542 108275 150431 205620 276921 367936\n24 38 52 61 53 10 -73 -138 42 1075 4356 12809 32195 73394 156469 318214 626801 1211053 2319569 4439602 8532786\n4 10 36 100 243 556 1233 2668 5629 11577 23262 45830 88824 169667 319485 592472 1080426 1934604 3397664 5849192 9869161\n-4 7 35 84 170 335 665 1316 2552 4799 8719 15308 26022 42935 68933 107948 165236 247703 364283 526372 748322\n-7 4 31 85 196 437 976 2172 4734 9973 20207 39455 74747 138831 256043 475047 895657 1722829 3370197 6649632 13104456\n16 32 58 111 217 410 745 1344 2499 4865 9805 20028 40853 82880 167863 341774 703534 1466538 3085872 6511449 13672565\n-5 -11 -19 -29 -41 -55 -71 -89 -109 -131 -155 -181 -209 -239 -271 -305 -341 -379 -419 -461 -505\n5 8 27 84 220 507 1078 2190 4332 8382 15798 28785 50293 83555 130708 190077 252623 301509 328232 401228 871348\n22 31 48 86 172 357 726 1417 2671 4960 9297 17952 36037 74887 159044 340266 724833 1525270 3155647 6402851 12728283\n13 26 37 45 58 113 311 867 2175 4888 10013 19021 33972 57655 93743 146963 223281 330102 476485 673373 933838\n12 37 78 151 286 522 901 1478 2383 3991 7275 14433 29888 61749 123771 237731 435898 762853 1275224 2036831 3105150\n8 21 55 123 237 408 646 960 1358 1847 2433 3121 3915 4818 5832 6958 8196 9545 11003 12567 14233\n3 19 44 71 100 149 259 491 916 1602 2605 3974 5783 8206 11654 16996 25889 41245 67866 113281 188822\n8 19 57 138 279 498 814 1247 1818 2549 3463 4584 5937 7548 9444 11653 14204 17127 20453 24214 28443\n9 4 5 23 80 223 554 1285 2829 5953 12058 23725 45786 87356 165507 311589 581617 1072658 1947779 3472867 6069516\n4 5 15 44 100 191 336 594 1120 2264 4761 10142 21660 46317 99077 211200 446093 928628 1898502 3807091 7495429\n15 29 52 91 168 327 635 1168 1976 3031 4181 5172 5894 7252 13693 39949 128019 387751 1089032 2861339 7106618\n4 27 76 163 300 499 772 1131 1588 2155 2844 3667 4636 5763 7060 8539 10212 12091 14188 16515 19084\n0 14 49 126 288 620 1290 2632 5308 10611 21004 41028 78750 147953 271285 484572 842448 1425348 2347731 3767130 5893244\n3 5 19 56 140 317 663 1291 2357 4065 6671 10486 15878 23273 33155 46065 62599 83405 109179 140660 178624\n15 24 50 100 174 275 432 735 1381 2730 5370 10190 18460 31917 52856 84225 129723 193900 282258 401352 558890\n3 10 28 67 151 337 751 1653 3540 7288 14321 26777 47618 80603 130010 199955 293113 408598 538706 664167 747489\n20 41 74 126 209 345 579 1013 1892 3804 8106 17770 38987 84130 177153 363333 726644 1420251 2718970 5107486 9425181\n15 27 39 51 63 75 87 99 111 123 135 147 159 171 183 195 207 219 231 243 255\n8 21 58 139 303 630 1288 2630 5374 10904 21738 42245 79828 147184 267217 484267 889432 1675307 3248534 6450147 12967977\n12 18 24 30 36 42 48 54 60 66 72 78 84 " <> ...}
23
+
```
24
+
25
+
```elixir
26
+
lines =
27
+
puzzle_input
28
+
|> String.split("\n", trim: true)
29
+
|> Enum.map(fn line ->
30
+
line
31
+
|> String.split()
32
+
|> Enum.map(&String.to_integer/1)
33
+
end)
34
+
```
35
+
36
+
<!-- livebook:{"output":true} -->
37
+
38
+
```
39
+
[
40
+
[27, 49, 92, 176, 327, 586, 1039, 1879, 3511, 6711, 12850, 24194, 44291, 78456, 134365, 222769,
41
+
358339, 560653, 855336, 1275364, 1862543],
42
+
[15, 25, 36, 57, 117, 286, 706, 1643, 3584, 7420, 14791, 28745, 55012, 104457, 197703, 373565,
43
+
703877, 1318603, 2446886, 4482001, 8081143],
44
+
[2, -1, -1, 5, 35, 140, 429, 1101, 2482, 5067, 9586, 17171, 29829, 51664, 91688, 169675, 327410,
45
+
648943, 1295161, 2560233, 4960367],
46
+
[17, 40, 75, 124, 195, 314, 553, 1083, 2269, 4852, 10332, 21799, 45683, 95258, 197352, 404834,
47
+
819561, 1634448, 3210609, 6218318, 11892083],
48
+
[12, 28, 47, 77, 148, 320, 690, 1410, 2740, 5170, 9648, 17942, 33138, 60228, 106667, 182671,
49
+
300884, 474856, 715541, 1024739, 1384064],
50
+
[23, 34, 56, 98, 179, 335, 630, 1192, 2323, 4773, 10330, 22981, 51089, 111404, 236460, 488303,
51
+
984007, 1942732, 3771076, 7214380, 13617999],
52
+
[-3, 9, 34, 76, 147, 268, 465, 760, 1157, 1623, 2064, 2296, 2011, 738, -2201, -7740, -17123,
53
+
-31963, -54306, -86700, -132269],
54
+
[2, 5, 10, 28, 85, 240, 617, 1451, 3148, 6359, 12068, 21694, 37207, 61258, 97323, 149861, 224486,
55
+
328153, 469358, 658352, 907369],
56
+
[2, 8, 19, 26, 30, 54, 164, 525, 1536, 4108, 10175, 23584, 51670, 108250, 219765, 438340, 869318,
57
+
1727304, 3445143, 6876026, 13651774],
58
+
[-7, -3, 9, 42, 129, 327, 726, 1476, 2850, 5366, 9996, 18495, 33888, 61158, 108183, 186975,
59
+
315279, 518595, 832691, 1306680, 2006739],
60
+
[14, 15, 24, 47, 93, 174, 306, 517, 868, 1493, 2664, 4887, 9035, 16524, 29538, 51309, 86458,
61
+
141403, 224840, 348303, 526809],
62
+
[-4, 10, 50, 125, 241, 410, 669, 1105, 1873, 3186, 5269, 8334, 12802, 20376, 37376, 83418, 211850,
63
+
554706, 1416484, 3461131, 8070127],
64
+
[15, 39, 76, 141, 268, 519, 996, 1856, 3329, 5739, 9528, 15283, 23766, 35947, 53040, 76542,
65
+
108275, 150431, 205620, 276921, 367936],
66
+
[24, 38, 52, 61, 53, 10, -73, -138, 42, 1075, 4356, 12809, 32195, 73394, 156469, 318214, 626801,
67
+
1211053, 2319569, 4439602, 8532786],
68
+
[4, 10, 36, 100, 243, 556, 1233, 2668, 5629, 11577, 23262, 45830, 88824, 169667, 319485, 592472,
69
+
1080426, 1934604, 3397664, 5849192, 9869161],
70
+
[-4, 7, 35, 84, 170, 335, 665, 1316, 2552, 4799, 8719, 15308, 26022, 42935, 68933, 107948, 165236,
71
+
247703, 364283, 526372, 748322],
72
+
[-7, 4, 31, 85, 196, 437, 976, 2172, 4734, 9973, 20207, 39455, 74747, 138831, 256043, 475047,
73
+
895657, 1722829, 3370197, 6649632, 13104456],
74
+
[16, 32, 58, 111, 217, 410, 745, 1344, 2499, 4865, 9805, 20028, 40853, 82880, 167863, 341774,
75
+
703534, 1466538, 3085872, 6511449, 13672565],
76
+
[-5, -11, -19, -29, -41, -55, -71, -89, -109, -131, -155, -181, -209, -239, -271, -305, -341,
77
+
-379, -419, -461, -505],
78
+
[5, 8, 27, 84, 220, 507, 1078, 2190, 4332, 8382, 15798, 28785, 50293, 83555, 130708, 190077,
79
+
252623, 301509, 328232, 401228, 871348],
80
+
[22, 31, 48, 86, 172, 357, 726, 1417, 2671, 4960, 9297, 17952, 36037, 74887, 159044, 340266,
81
+
724833, 1525270, 3155647, 6402851, 12728283],
82
+
[13, 26, 37, 45, 58, 113, 311, 867, 2175, 4888, 10013, 19021, 33972, 57655, 93743, 146963, 223281,
83
+
330102, 476485, 673373, 933838],
84
+
[12, 37, 78, 151, 286, 522, 901, 1478, 2383, 3991, 7275, 14433, 29888, 61749, 123771, 237731,
85
+
435898, 762853, 1275224, 2036831, 3105150],
86
+
[8, 21, 55, 123, 237, 408, 646, 960, 1358, 1847, 2433, 3121, 3915, 4818, 5832, 6958, 8196, 9545,
87
+
11003, 12567, 14233],
88
+
[3, 19, 44, 71, 100, 149, 259, 491, 916, 1602, 2605, 3974, 5783, 8206, 11654, 16996, 25889, 41245,
89
+
67866, 113281, 188822],
90
+
[8, 19, 57, 138, 279, 498, 814, 1247, 1818, 2549, 3463, 4584, 5937, 7548, 9444, 11653, 14204,
91
+
17127, 20453, 24214, 28443],
92
+
[9, 4, 5, 23, 80, 223, 554, 1285, 2829, 5953, 12058, 23725, 45786, 87356, 165507, 311589, 581617,
93
+
1072658, 1947779, 3472867, 6069516],
94
+
[4, 5, 15, 44, 100, 191, 336, 594, 1120, 2264, 4761, 10142, 21660, 46317, 99077, 211200, 446093,
95
+
928628, 1898502, 3807091, 7495429],
96
+
[15, 29, 52, 91, 168, 327, 635, 1168, 1976, 3031, 4181, 5172, 5894, 7252, 13693, 39949, 128019,
97
+
387751, 1089032, 2861339, 7106618],
98
+
[4, 27, 76, 163, 300, 499, 772, 1131, 1588, 2155, 2844, 3667, 4636, 5763, 7060, 8539, 10212,
99
+
12091, 14188, 16515, ...],
100
+
[0, 14, 49, 126, 288, 620, 1290, 2632, 5308, 10611, 21004, 41028, 78750, 147953, 271285, 484572,
101
+
842448, 1425348, 2347731, ...],
102
+
[3, 5, 19, 56, 140, 317, 663, 1291, 2357, 4065, 6671, 10486, 15878, 23273, 33155, 46065, 62599,
103
+
83405, ...],
104
+
[15, 24, 50, 100, 174, 275, 432, 735, 1381, 2730, 5370, 10190, 18460, 31917, 52856, 84225, 129723,
105
+
...],
106
+
[3, 10, 28, 67, 151, 337, 751, 1653, 3540, 7288, 14321, 26777, 47618, 80603, 130010, 199955, ...],
107
+
[20, 41, 74, 126, 209, 345, 579, 1013, 1892, 3804, 8106, 17770, 38987, 84130, 177153, ...],
108
+
[15, 27, 39, 51, 63, 75, 87, 99, 111, 123, 135, 147, 159, 171, ...],
109
+
[8, 21, 58, 139, 303, 630, 1288, 2630, 5374, 10904, 21738, 42245, 79828, ...],
110
+
[12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, ...],
111
+
[0, 4, 25, 68, 141, 272, 548, 1191, 2693, 6050, 13171, ...],
112
+
[4, -3, -3, 13, 61, 170, 394, 850, 1809, 3869, ...],
113
+
[-7, -12, -10, 18, 99, 265, 551, 994, 1633, ...],
114
+
[10, 11, 22, 61, 152, 325, 616, 1067, ...],
115
+
[-3, 8, 30, 79, 184, 392, 785, ...],
116
+
[2, 3, 19, 75, 213, 511, ...],
117
+
[1, 16, 38, 75, 146, ...],
118
+
[3, 25, 64, 128, ...],
119
+
[15, 31, 66, ...],
120
+
[27, 52, ...],
121
+
[6, ...],
122
+
[...],
123
+
...
124
+
]
125
+
```
126
+
127
+
```elixir
128
+
defmodule Day09 do
129
+
def extrapolate(list, field \\ &List.last/1) do
130
+
reduce(list, [field.(list)], field)
131
+
end
132
+
133
+
defp reduce(list, acc, field) do
134
+
if Enum.all?(list, &(&1 == 0)) do
135
+
acc
136
+
else
137
+
new =
138
+
list
139
+
|> Enum.chunk_every(2, 1, :discard)
140
+
|> Enum.map(fn [a, b] -> b - a end)
141
+
142
+
reduce(new, [field.(new) | acc], field)
143
+
end
144
+
end
145
+
end
146
+
```
147
+
148
+
<!-- livebook:{"output":true} -->
149
+
150
+
```
151
+
{:module, Day09, <<70, 79, 82, 49, 0, 0, 10, ...>>, {:reduce, 3}}
152
+
```
153
+
154
+
## Part 1
155
+
156
+
```elixir
157
+
lines
158
+
|> Enum.map(fn line ->
159
+
Day09.extrapolate(line)
160
+
|> Enum.reduce(&+/2)
161
+
end)
162
+
|> Enum.sum()
163
+
```
164
+
165
+
<!-- livebook:{"output":true} -->
166
+
167
+
```
168
+
1842168671
169
+
```
170
+
171
+
## Part 2
172
+
173
+
```elixir
174
+
lines
175
+
|> Enum.map(fn line ->
176
+
Day09.extrapolate(line, &List.first/1)
177
+
|> Enum.reduce(&-/2)
178
+
end)
179
+
|> Enum.sum()
180
+
```
181
+
182
+
<!-- livebook:{"output":true} -->
183
+
184
+
```
185
+
903
186
+
```
187
+
188
+
<!-- livebook:{"offset":11034,"stamp":{"token":"XCP.4niSRZnU_1qf0GtnoryY24xBSp3eHuDV770anpiMIG4QlQY1-YQrGuwXL43UbHafeRUdUytg7ITWDNnIHchGL1JYNXi-59qaGTyx0nfkbcwCqqLa0ukaCsTcU-1fFxEk3w","version":2}} -->
+264
2023/day10.livemd
+264
2023/day10.livemd
···
1
+
<!-- livebook:{"persist_outputs":true} -->
2
+
3
+
# Day 10
4
+
5
+
```elixir
6
+
Mix.install([:kino_aoc])
7
+
```
8
+
9
+
## Section
10
+
11
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"10","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", "10", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
16
+
```
17
+
18
+
<!-- livebook:{"output":true} -->
19
+
20
+
```
21
+
{:ok,
22
+
"|-L.FL-FJFL.|7FJ7F|F7-7F77.FL7---.7FF77--.|-F|FF--7FF7F-7F--77FFFJFJF7.F-LF7LFJJ.F|.|77F7F---7FLL.|FFJ.FF7-77..F77.-F-7FL-FF|77F-FFLL-FJ-|.J\n|7JF77-|L7J-F-JJL7|-|LJLF-|7.|.LLLJ7|-7.LFJFF--JF7L7|||FJ|F-J77L|F7.L-FJF----L7.FF.FJ-J-L-7|L|LJ7FJJJ.F|L-7L7.FF-|-7F-|J..||LJ-|-J-.|L|J|LF|\nLJ-LL|F7|LL7LLL-|-F7||..||..FJ.FJJF-7JJ|.7JLL--7|L7LJLJ|FJL-77|..FFJ7FJ7L7-|-JL.F--7LJJ|LJJ.F-|L7.FF-L7-F-7F77|J7||FLFJ|FFLL7.|JFJJ--J|.7-7|\n|.FJ.|F7-7L77|||L7JL-7LF777-JJ.|7F-L7JFJ7|F-|.LLJ|L---7||F--J7JFLF|JF-.--7||J.|F-.7LLLFF7||7F777L7FJ-||LJ7|||F|L-7.JJ.||7||J7.|-LL.7J.F7L7--\nF-7LF||.FLJL-7|FF|L7FL-L||F-7|FL7LJ|L7L|.LLJ|FJJLF---7|||L---7L7|L|7||FLFLJ|-FF-7|777FJ7|-FFJ|L77LL-F.JJJL7LLJ.|L7FJFF-77LF-7-|-|77L|7.L--7|\nF-JF-L7--J|JLL7-|LJ|F|J7L|J.J-|F7J7F|JF-7.|LF7F77L--7||LJF---JL-JJ|LJ7FJL7L|JLFJF|7FF7.-JJFL7|-F77J-777JF|L7J.|--L|J7|7LJ7JFJJ..|-J--7.L7.FJ\nL7J|7||J--L-F7.||LFL-JF7.F7.|.FL7.FF7L|7F|FF-7F-7F7FJLJF7L----7JFFJJ.J|7L|7L7JLL|JFFJ7.|.|F-J|FJL7|F7-|F7JF|FF.|.||7L-J7LF-||.L7J7L7FJ7.L-.|\nL7.L-FJJJF|FJ-.|JF--J7FJ7LLJ-..LJF||L-7F-7-L7|L7|||L--7|L-----J-FF-F7FL77|---F7JLL-|JF-77FL-7LJF-JFJ|-|-7-7L-7-7-JLJ-|L7-JJLF7-J-7|L77JFJJ.|\nLL-|FJL7.L|J7|-L7F.|FL-.FJJ.F-F-F-7L-7LJFJ|F|L-JLJL7F7|L----7|.F7F7F7JJ-L--|JJ7|-7-LF|FJF7J|L-7||FJFJ.LLJ.77||.L.LF7LF-F77F-J.F7-J7L-F7FJF-.\nFJ.|J7L77-7LL7J-7---FJ-FL---|||FJFJLLL-7|F7FL-----7||||F--7FJ-FJ||LJ||..LF7|JL--F||.FJL7||LF-7|L7|FJF7-.F-LJ.-7.F7.77F7||7-|L7LJJJFJ.FJJF-L.\n|.F|F7-.|.JJ.L..L|JL7..FJL|FF-7L7L-7F--JLJ|7LF7F--JLJLJ|F7LJJFL7||F-J--J7|7..F|-FL|FL7FJ|L7L7LJFJ|L7||7F|J|L7.F7F77.FJ||L--7--7|7.L-7L-77J|7\nLF-LL.L7J.FF-.F-||--.|-|-F--|FJ7L-7|L--7F7|F-J||F7F---7|||F7LFFJLJL7JL|.FF-77FF7JJF77|||L7L-JF-JLL7||L7F7|F-|.||||LFL7||F7FJ-LJ-77J-J7.LJF7J\nFF.|..7JJ7FLJ7|L-7F|F|.|7LLL|L7F--JL7F7||LJL7FJLJLJLF7|||LJL7FJF---J-|F77|JL7L|||FJL-JL-7L--7L7F7FJ|L7||L7L-F-J|||F7F||||LJ7LLJ.7JFFLF-L7LJ-\nL.FJ-|77--F||F77JJLF-7-J7F7LL7||F--7||LJL7|FJL-7F--7|||LJF--JL7|F-7JF--F7|.L7.|L7L----7FJF7FJFJ||L7|FJ||FJ77L-7LJ||L-JLJL7-|..-.|F7--77LJ-|J\nF|.L7||--FLJ7.L7F-J|FJJFF7FF7||LJF7||L7F7L7L7F-JL-7||||F-JLF-7|LJFJ7JFLF--77L-L7|7FF-7|L7||L7L7||FJ|L7LJ|F7F-7|F-JL--7F--J7F|J-F|7|LLJL7JF|.\nJ|LF|FJFFL.|F7LLJ|.|L7F7||FJLJL--JLJL7LJL7L7|L--7FJLJLJ|LF-JFJ|F-JF7.|.L7FJF7JFJL7FJFJ|FJ||7L7||LJFJ7L7FJ||L7|||F-7F7||F7LLJJ7.FJ.F77JF|F7|F\n||JFJ|F|J|7|JJL|-7-L7LJ|||L-7F7F--7F7L7F7L7LJF--JL--7F7L7|F-JFJL-7||-F-7||FJL7L7FJL7L-JL7||F-JLJF-JLF-JL-J|FJLJLJFJ|LJLJ|7J.F|7LJL|--7FJF|||\nL7--.LLJJ--|.FFJF-7-L-7||L-7LJ||F7LJL7LJL7L-7L-7F7F-J|L7LJL77L7F-J|L7L7|||L-7|FJL7FJF-7FJ||L-7F7|F7JL7F7F-JL--7F-J|L--7FJF77J|F|JLL7FLFLLJ|F\n.JLLF77.L-.|.LJ-7||FF-J||F-JF7LJ|L--7L-7FJF7|F-J||L--JLL-7FJF7||F7L7|FJ||L7FJLJF-JL-J||L7|L-7LJ|||L7FJ|||JF7F-J|F--7F-JL-JL7F---7JJ|F-JJ7LL-\n7-F7|FLJ7|7L-|.FJFL-L-7||L7FJL7LL-7FJF7|L-JLJL-7|L7F-7F7FJ|FJLJLJL7||L7||FJL-7FJF7F7F7|FJ|F-JF7|||FJ|FJLJFJ|L-7||F-JL--7F-7LJF--JJ7||||.7F|.\nL7LL|J|FFJ7FL7.FFJFFF-JLJFJL7FJF7FJ|FJ||F7F---7||FJL7||||FJ|F-7F7FJ||FJLJL7FFJL-J||LJLJL7|L-7||||||L||F7FJFJF-JLJ|F7F7FJL7L7FJF7.F7J-FF.FL-7\nLJ.LL7-J-JL|F|F---7FJF7F7L-7|L7|LJFJL7|LJLJF7FJLJL-7|LJ|||L||7LJLJJ|||F---JFJF---JL---7FJ|F-J|LJ||L7||||L7||L---7LJ|||L7FJ-|L-JL-J|.F-JFF.L7\nFJF|.L--L|-FLFL--7|L7||||F-J|FJL-7L7FJ|7F--JLJF----JL-7LJL7|L---7F7|LJL-7F7|FJF-7F-7F7|L7|L-7L7FJ|FJ|||L7|L7-F-7L-7LJL-JL-7L--7F--J.|.7JL|L|\nF-|77FJLFFJ|J.|F7|L7LJLJ||F-JL7F7L7|L7L7L----7L----7F7L-7FJ|F---J||L---7||LJL7L7|L7|||L7||F-JFJL-J|FJ||FJ|FJFJFJF7|F---7F7L7.LLJJJ.--7J.F777\n|..77-L-7-.LF7FJLJFJ7FF-J|L--7||L7||FJFJF7F7L|F---7|||F7|L7|L--7FJL7F7FJ||F7FJFJ|FJLJL7|||L7FJF7F-JL7LJL7|L-JFJFJLJ|F7F|||FJ-LJ|LLL.J|F-F.|.\n-7-LL|7FJ7L-|-|F-7L--7L-7|F7L|||FJ||L7|F|||L7||JF7LJ|LJ|L7||F--JL7FJ||L7|||LJL|FJL---7||||FJ|FJLJF--JF--J|F--JFJF--J|L7|||L7JFFF7L|7.L|F77J7\nF|7J.-J-LL7L-JLJ7L7F-JF-JLJL-JLJ|FJL7|L7||L7LJL7||F7L-7L7|||L-7F7|L7|L7|||L---JL7F-7FJ||LJL-J|FF7L-7FJ|F-JL7F7L7L7F7|FJLJL-J-F-7.F|F7JL-JFFF\nFLF.LLL7|.|-7.F7F7||F7L-------7FJL7FJL7|||LL7F-J|||L--JFJ|||F-J|||FJL7||LJF-----JL7||FJ|F---7L-J|F7||F7L--7|||.|FJ|LJ|F7.F7|7L7L7-J|FJL|LLJJ\nLJ.|7|LF|7J.LFJLJLJLJL7F--7F--JL--JL7FJ|||F-JL-7||L---7|FJLJL-7|LJL77|||F-JF-7-F7FJLJ|7LJF--JF--J|||LJ|FF7|||L-JL-JF7LJ|FJL77FJFJ|.JJ7F-J|||\nFF-|-J|" <> ...}
23
+
```
24
+
25
+
```elixir
26
+
# puzzle_input =
27
+
"""
28
+
...........
29
+
.S-------7.
30
+
.|F-----7|.
31
+
.||.....||.
32
+
.||.....||.
33
+
.|L-7.F-J|.
34
+
.|..|.|..|.
35
+
.L--J.L--J.
36
+
...........
37
+
"""
38
+
```
39
+
40
+
<!-- livebook:{"output":true} -->
41
+
42
+
```
43
+
"...........\n.S-------7.\n.|F-----7|.\n.||.....||.\n.||.....||.\n.|L-7.F-J|.\n.|..|.|..|.\n.L--J.L--J.\n...........\n"
44
+
```
45
+
46
+
```elixir
47
+
defmodule Day10 do
48
+
@pipes %{
49
+
?| => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
50
+
?- => %{e: {{1, 0}, :e}, w: {{-1, 0}, :w}},
51
+
?L => %{s: {{1, 0}, :e}, w: {{0, -1}, :n}},
52
+
?J => %{s: {{-1, 0}, :w}, e: {{0, -1}, :n}},
53
+
?7 => %{n: {{-1, 0}, :w}, e: {{0, 1}, :s}},
54
+
?F => %{n: {{1, 0}, :e}, w: {{0, 1}, :s}}
55
+
}
56
+
57
+
for {k, v} <- @pipes do
58
+
v = Macro.escape(v)
59
+
def symbol_to_map(unquote(k)), do: unquote(v)
60
+
def map_to_symbol(unquote(v)), do: unquote(k)
61
+
end
62
+
63
+
def symbol_to_map(?S), do: :start
64
+
def map_to_symbol(nil), do: nil
65
+
66
+
@around [
67
+
{{0, -1}, :n, :s},
68
+
{{0, 1}, :s, :n},
69
+
{{-1, 0}, :w, :e},
70
+
{{1, 0}, :e, :w}
71
+
]
72
+
73
+
def start(map) do
74
+
{sx, sy} = start = Enum.find_value(map, fn {k, v} -> if v == :start, do: k end)
75
+
76
+
routes =
77
+
for {{dx, dy}, face_next, route} <- @around,
78
+
pipe = map[{sx + dx, sy + dy}] || %{},
79
+
Map.has_key?(pipe, face_next),
80
+
do: route
81
+
82
+
dbg(routes)
83
+
smap = start_to_map(routes)
84
+
begin = smap |> Map.values() |> hd()
85
+
start_map = Map.merge(smap, %{start: begin})
86
+
87
+
{start, Map.put(map, start, start_map)}
88
+
end
89
+
90
+
defp start_to_map(next) do
91
+
Enum.find_value(@pipes, fn {_, map} ->
92
+
if Enum.all?(next, &Map.has_key?(map, &1)), do: map
93
+
end)
94
+
end
95
+
end
96
+
```
97
+
98
+
<!-- livebook:{"output":true} -->
99
+
100
+
```
101
+
{:module, Day10, <<70, 79, 82, 49, 0, 0, 20, ...>>, {:start_to_map, 1}}
102
+
```
103
+
104
+
```elixir
105
+
pipes =
106
+
for {line, y} <- Enum.with_index(String.split(puzzle_input)),
107
+
{segment, x} <- Enum.with_index(String.to_charlist(line)),
108
+
segment in ~c'|-LJ7FS',
109
+
into: %{} do
110
+
{{x, y}, Day10.symbol_to_map(segment)}
111
+
end
112
+
113
+
{start, pipes} = Day10.start(pipes)
114
+
115
+
dbg(pipes[start])
116
+
117
+
rat =
118
+
Stream.unfold({start, :start}, fn {{x, y} = pos, face} ->
119
+
{{dx, dy}, f} = pipes[pos][face]
120
+
next_pos = {x + dx, y + dy}
121
+
122
+
{next_pos, {next_pos, f}}
123
+
end)
124
+
```
125
+
126
+
<!-- livebook:{"output":true} -->
127
+
128
+
```
129
+
[:n, :e]
130
+
```
131
+
132
+
<!-- livebook:{"output":true} -->
133
+
134
+
```
135
+
%{start: {{0, 1}, :s}, e: {{0, 1}, :s}, n: {{-1, 0}, :w}}
136
+
```
137
+
138
+
<!-- livebook:{"output":true} -->
139
+
140
+
```
141
+
#Function<63.53678557/2 in Stream.unfold/2>
142
+
```
143
+
144
+
## Part 1
145
+
146
+
```elixir
147
+
length =
148
+
rat
149
+
|> Stream.with_index(1)
150
+
|> Enum.find_value(fn {p, idx} -> if p == start, do: idx end)
151
+
152
+
div(length, 2)
153
+
```
154
+
155
+
<!-- livebook:{"output":true} -->
156
+
157
+
```
158
+
7066
159
+
```
160
+
161
+
## Part 2
162
+
163
+
```elixir
164
+
map =
165
+
rat
166
+
|> Enum.take(length + 1)
167
+
|> Map.new(&{&1, pipes[&1]})
168
+
```
169
+
170
+
<!-- livebook:{"output":true} -->
171
+
172
+
```
173
+
%{
174
+
{18, 103} => %{e: {{0, 1}, :s}, n: {{-1, 0}, :w}},
175
+
{61, 121} => %{w: {{0, 1}, :s}, n: {{1, 0}, :e}},
176
+
{112, 138} => %{s: {{1, 0}, :e}, w: {{0, -1}, :n}},
177
+
{37, 47} => %{e: {{0, 1}, :s}, n: {{-1, 0}, :w}},
178
+
{77, 129} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
179
+
{120, 47} => %{s: {{-1, 0}, :w}, e: {{0, -1}, :n}},
180
+
{116, 69} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
181
+
{124, 56} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
182
+
{117, 125} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
183
+
{32, 15} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
184
+
{103, 106} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
185
+
{30, 113} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
186
+
{123, 104} => %{e: {{0, 1}, :s}, n: {{-1, 0}, :w}},
187
+
{89, 14} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
188
+
{35, 30} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
189
+
{37, 53} => %{w: {{0, 1}, :s}, n: {{1, 0}, :e}},
190
+
{77, 130} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
191
+
{78, 98} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
192
+
{101, 62} => %{w: {{0, 1}, :s}, n: {{1, 0}, :e}},
193
+
{95, 56} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
194
+
{102, 74} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
195
+
{11, 39} => %{w: {{0, 1}, :s}, n: {{1, 0}, :e}},
196
+
{65, 43} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
197
+
{22, 38} => %{s: {{1, 0}, :e}, w: {{0, -1}, :n}},
198
+
{14, 86} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
199
+
{49, 117} => %{e: {{0, 1}, :s}, n: {{-1, 0}, :w}},
200
+
{20, 41} => %{s: {{-1, 0}, :w}, e: {{0, -1}, :n}},
201
+
{29, 25} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
202
+
{86, 10} => %{w: {{0, 1}, :s}, n: {{1, 0}, :e}},
203
+
{83, 36} => %{e: {{0, 1}, :s}, n: {{-1, 0}, :w}},
204
+
{29, 26} => %{s: {{-1, 0}, :w}, e: {{0, -1}, :n}},
205
+
{47, 27} => %{s: {{-1, 0}, :w}, e: {{0, -1}, :n}},
206
+
{31, 42} => %{s: {{-1, 0}, :w}, e: {{0, -1}, :n}},
207
+
{120, 42} => %{e: {{0, 1}, :s}, n: {{-1, 0}, :w}},
208
+
{121, 77} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
209
+
{103, 39} => %{s: {{1, 0}, :e}, w: {{0, -1}, :n}},
210
+
{102, 57} => %{e: {{0, 1}, :s}, n: {{-1, 0}, :w}},
211
+
{32, 111} => %{e: {{0, 1}, :s}, n: {{-1, 0}, :w}},
212
+
{84, 102} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
213
+
{67, 98} => %{s: {{-1, 0}, :w}, e: {{0, -1}, :n}},
214
+
{119, 60} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
215
+
{116, 96} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
216
+
{13, 85} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
217
+
{82, 60} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
218
+
{132, 99} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
219
+
{111, 108} => %{s: {{1, 0}, :e}, w: {{0, ...}, :n}},
220
+
{111, 103} => %{s: {{-1, ...}, :w}, e: {{...}, ...}},
221
+
{15, 92} => %{e: {{...}, ...}, n: {...}},
222
+
{58, ...} => %{s: {...}, ...},
223
+
{...} => %{...},
224
+
...
225
+
}
226
+
```
227
+
228
+
```elixir
229
+
{min_x, max_x, min_y, max_y} =
230
+
Enum.reduce(Map.keys(map), {:inf, -1, :inf, -1}, fn {x, y}, {min_x, max_x, min_y, max_y} ->
231
+
{min(min_x, x), max(max_x, x), min(min_y, y), max(max_y, y)}
232
+
end)
233
+
234
+
Enum.reduce(min_y..max_y, 0, fn y, acc ->
235
+
{_, new_acc, _} =
236
+
Enum.reduce(min_x..max_x, {_in? = false, acc, nil}, fn x, {in?, count, cut} ->
237
+
pos = {x, y}
238
+
pipe = Day10.map_to_symbol(map[pos])
239
+
240
+
case {in?, cut, pipe} do
241
+
# Empty - count
242
+
{true, _, nil} -> {true, count + 1, nil}
243
+
{false, _, nil} -> {false, count, nil}
244
+
# Keeping same in? over dead ends or horizontal pipes
245
+
{in?, ?F, ?J} -> {in?, count, nil}
246
+
{in?, ?L, ?7} -> {in?, count, nil}
247
+
{in?, cut, ?-} -> {in?, count, cut}
248
+
# crossing pipes
249
+
{in?, _, cut} when cut in ~c[FL] -> {not in?, count, cut}
250
+
{in?, _, _} -> {not in?, count, nil}
251
+
end
252
+
end)
253
+
254
+
new_acc
255
+
end)
256
+
```
257
+
258
+
<!-- livebook:{"output":true} -->
259
+
260
+
```
261
+
401
262
+
```
263
+
264
+
<!-- livebook:{"offset":10970,"stamp":{"token":"XCP.eg8I0JKuYGKRQ6ZLEkgXh_CgBWFloHr69nddniRhrGb8VYehWkNOR5xKnO3pCjta4lPqCOhary3a6WOL4GEwXCX8z-X23nu4atIlpcMYS7lwpipAaHv0JWjqM8DTukYlMg","version":2}} -->
+125
2023/day11.livemd
+125
2023/day11.livemd
···
1
+
<!-- livebook:{"persist_outputs":true} -->
2
+
3
+
# Day 11
4
+
5
+
```elixir
6
+
Mix.install([:kino_aoc])
7
+
```
8
+
9
+
## Section
10
+
11
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"11","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", "11", 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.....#." <> ...}
23
+
```
24
+
25
+
```elixir
26
+
lines = String.split(puzzle_input, "\n", trim: true)
27
+
28
+
galaxies =
29
+
for {line, y} <- Enum.with_index(lines),
30
+
{d, x} <- Enum.with_index(String.to_charlist(line)),
31
+
d == ?#,
32
+
do: {x, y}
33
+
34
+
{sx, sy} =
35
+
Enum.reduce(galaxies, {0, 0}, fn {x, y}, {mx, my} -> {max(x, mx), max(y, my)} end)
36
+
```
37
+
38
+
<!-- livebook:{"output":true} -->
39
+
40
+
```
41
+
{139, 139}
42
+
```
43
+
44
+
```elixir
45
+
[rows, cols] =
46
+
Enum.reduce(galaxies, [MapSet.new(), MapSet.new()], fn {x, y}, [rows, cols] ->
47
+
[MapSet.put(rows, y), MapSet.put(cols, x)]
48
+
end)
49
+
50
+
empty_rows = MapSet.difference(MapSet.new(0..sy), rows) |> MapSet.to_list() |> Enum.sort()
51
+
empty_cols = MapSet.difference(MapSet.new(0..sx), cols) |> MapSet.to_list() |> Enum.sort()
52
+
53
+
{empty_rows, empty_cols}
54
+
```
55
+
56
+
<!-- livebook:{"output":true} -->
57
+
58
+
```
59
+
{[23, 54, 77, 81, 87, 91, 106, 107], ~c".178SYh"}
60
+
```
61
+
62
+
```elixir
63
+
defmodule Day11 do
64
+
def reduce_unique_pairs(xs, init, fun) when is_function(fun, 3) do
65
+
do_map(hd(xs), tl(xs), fun, init)
66
+
end
67
+
68
+
def do_map(_h, [], _fun, acc), do: acc
69
+
70
+
def do_map(a, xs, fun, acc) do
71
+
new =
72
+
Enum.reduce(xs, acc, fn b, acc1 -> fun.(a, b, acc1) end)
73
+
74
+
do_map(hd(xs), tl(xs), fun, new)
75
+
end
76
+
77
+
def expand({x, y}, empty_rows, empty_cols, m \\ 2) do
78
+
{x + delta(x, empty_cols) * (m - 1), y + delta(y, empty_rows) * (m - 1)}
79
+
end
80
+
81
+
defp delta(p, empty) do
82
+
Enum.count(empty, &(p > &1))
83
+
end
84
+
end
85
+
```
86
+
87
+
<!-- livebook:{"output":true} -->
88
+
89
+
```
90
+
{:module, Day11, <<70, 79, 82, 49, 0, 0, 12, ...>>, {:delta, 2}}
91
+
```
92
+
93
+
## Part 1
94
+
95
+
```elixir
96
+
galaxies
97
+
|> Enum.map(&Day11.expand(&1, empty_rows, empty_cols))
98
+
|> Day11.reduce_unique_pairs(0, fn {xa, ya}, {xb, yb}, acc ->
99
+
acc + abs(xb - xa) + abs(yb - ya)
100
+
end)
101
+
```
102
+
103
+
<!-- livebook:{"output":true} -->
104
+
105
+
```
106
+
9686930
107
+
```
108
+
109
+
## Part 2
110
+
111
+
```elixir
112
+
galaxies
113
+
|> Enum.map(&Day11.expand(&1, empty_rows, empty_cols, 1_000_000))
114
+
|> Day11.reduce_unique_pairs(0, fn {xa, ya}, {xb, yb}, acc ->
115
+
acc + abs(xb - xa) + abs(yb - ya)
116
+
end)
117
+
```
118
+
119
+
<!-- livebook:{"output":true} -->
120
+
121
+
```
122
+
630728425490
123
+
```
124
+
125
+
<!-- livebook:{"offset":6621,"stamp":{"token":"XCP.eVlqF57ZVWEep_9Yi2Bop2YbV2ltU4T8e1DrVKC83DPGypJtqq5uBZpnlG1ix3mgZ2cTntGIcUv867ImHAf_1T32D0t35IKejAKx886nb4XpUxf8FuS27jeNiQIFpCl4Pg","version":2}} -->
+184
2023/day12.livemd
+184
2023/day12.livemd
···
1
+
<!-- livebook:{"persist_outputs":true} -->
2
+
3
+
# Day 12
4
+
5
+
```elixir
6
+
Mix.install([:kino_aoc])
7
+
```
8
+
9
+
## Section
10
+
11
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"12","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", "12", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
16
+
```
17
+
18
+
<!-- livebook:{"output":true} -->
19
+
20
+
```
21
+
{:ok,
22
+
".#??..#??.?. 3,1,1,1\n???.##??#??????#???# 1,13,1\n.??#.?#??#????#?? 2,4,1,1,1\n???#??#.???#.?#??#?# 4,2,1,2,1,4\n????#?##???#.??.? 2,2,6,1\n.?????#???.###.##? 7,3,2\n.###?..#??????#???? 4,8,1\n??????????????? 1,1,1,2,1\n???.????????#? 1,3,1,1\n???.#..?#.?#?#??#?. 2,1,1,5,1\n.?..??#.????. 1,3,1,2\n.#?.??#?????##.# 1,2,1,3,1\n?###????.#?? 5,1,2\n?#??.????? 2,4\n?.#????#?????#??#?? 1,6,1,4,1\n#????????#?#?? 1,7,1,1\n?#??.?????? 3,1,1\n?..??#?###?? 1,6\n???.?.??#??##?? 1,1,1,5,1\n#???#.?????? 2,1,3,1\n?###??.??.?#???..? 4,1,2,1,1,1\n?.#???#?.?? 2,1,1\n#??##????##??????#? 7,5,2\n????#????????????# 1,6,1,1,2\n#?.?.##???? 1,1,5\n.?????.?#???????? 1,2,2,2,1\n#??.???#?.????? 2,5,1,1\n?????????.#???. 6,2\n?????????? 1,1,4\n?#??#??#?## 1,7\n????#?##???#? 1,6,1,1\n??#??#.???#?????? 1,1,1,7,1\n?????##?.?#??. 1,2,4\n???##????###????. 4,7\n?.?.?.?#???? 1,1,6\n???..??.????.###??. 2,2,2,5\n????##??#????? 1,7,1,1\n???..????#??? 2,6\n.??.????????. 1,2\n?.#?.????? 1,2\n??????.#???#? 2,5\n?????#.###???#.???# 6,7,1,1\n##.????##..#??#?. 2,6,1,1\n?????.??.?????????. 1,6\n??????..#?# 4,3\n#??????#??..?#? 10,2\n?.?????.?#??? 1,2\n???#??????.. 2,4\n.#?#???####??.?#?##? 12,5\n?.?????##??? 3,4\n?###?###????????# 10,3\n.?????????#? 1,5\n#?##????#???? 1,2,2,1\n.??????.??#???. 1,2,1,1,1\n??#.?#.????# 1,2,1,1\n???????.?#??????.?? 2,1,1,8,1\n???#??.?#???? 5,2,2\n?#??????###???. 2,8\n.??????#???????#? 1,12\n??..???#?#??? 1,6\n?.??????.. 1,1,3\n??#??.?#??#. 1,1,1,1\n?#?????.??????. 1,1,6\n.#?#?????#?#???#?.?? 5,9\n???#???#.#?##????? 5,1,7,1\n?#.??#??#?..?? 1,5,1\n#???#????#?.? 1,1,6,1\n????????.#? 4,1\n????#?#?#??.??.?? 8,1\n???#?????#?#?..#? 4,1,4,1\n??.??????#??.?#??#. 1,3,1,1\n.????????????? 1,2,2,1\n#.?#?#?#?.??? 1,6,1\n?#??#??..?#?? 3,2,3\n..#?.?#??#?# 2,6\n???#?.?..???## 3,1,2\n?????.?#?.???## 3,3,3\n??.?????..????? 3,5\n?.?????##? 1,1,2\n?.??#.#????#???.. 1,3,1,1,4\n??#??#?#?##????.# 3,3,6,1\n?.?.?.?####???.#. 1,8,1\n?##?????#?.?#.. 3,1,1,2,1\n???#???????.#. 2,4,1\n????.??.?#???? 1,3\n.?#?#?#??????##??? 2,11,2\n??.?#?.#?. 2,2,2\n????#...?#???# 4,5\n.??..???#??#?#? 2,1,1,3\n????#.?????? 3,6\n????.?????? 1,1,2\n????#?????.?# 1,2,2,2\n.?#?????.??.? 3,1,1,1\n???#??.?#.??. 1,3,2,2\n?##???????#???????# 2,9,1\n?##?????????.?? 8,1\n.#???????.??#???? 1,4,4\n.?#?.#??.? 1,1,1\n??.?#??????#? 4,3\n??#?#??#??.?? 3,2,1\n.#?.???##? 1,5\n?????.#?.???#? 2,1,1,4\n##????#??? 4,1,1\n?????????# 1,2,3\n??#?#?????##? 4,3\n?#.???##?#????#?##. 1,12\n#.?##???#???..??.?? 1,6,1,2,1\n?#????#??#.#?.##?# 5,1,1,1,4\n?#????#.#??#..? 1,3,1,1,1\n??###?.?.????. 5,2\n.????????#.#? 5,2,1\n.?.#.???..??#.?? 1,1,1,3,1\n#????????.??????. 4,4,2,1,1\n?.??????#? 3,3\n...?#.#.???##? 2,1,1,2\n??????????#.???.?#?? 7,1,1,1\n.????##?#??.???#???? 7,5\n??.#?.???? 1,2,2\n?.#??#??#?? 1,4,2\n????#?????? 1,4,2\n??.???????? 1,1,2\n??#????????#??#???? 3,3,7\n?????????##?.??#?. 1,1,2,1,3,2\n??#????????????.??? 2,11\n??#?.?#???#?##????. 4,3,4,1\n????.???????.?? 1,3\n????#.##?? 1,1,4\n#?????#?????.##?## 2,7,5\n#??.??..?#?#.? 2,1,4\n.??.??.?.?????##? 1,1,1,4\n??.???????#??? 1,7,1\n.#.??.?##???#.? 1,1,3,2,1\n#??.??##??.?#?.#?#?? 3,4,1,4\n???..?????????.# 2,1,3,1,1\n??#.?????#?##.?#.# 2,6,2,1,1\n?#?.?.#??#?? 1,6\n?###????#?.? 6,2\n?.?????????????.?? 1,1,1,1,4,1\n????.?#?##??#??. 1,1,5,2\n???????.????# 1,1,1,3\n##???.????#???# 2,1,1,1,5\n.#?##???####?.??#.?? 4,5,2\n????????#?#?.?#?? 1,1,3,1,3\n?.?????#?. 2,2\n?#???????????#.????? 7,2,1,1,1\n????????#..##. 1,2,2,2\n#?#?##?#??. 3,5\n???#????###????????. 17,1\n.????#???## 1,3,4\n??####??#??#?#?#?#?? 6,6,4\n??????#????.?.?? 1,3,1,1,1\n..?##?.?.?. 3,1\n.???####?????#? 8,1\n.???????#?..??.?# 1,3,1,2,1\n??.?#?????? 1,2,2\n??#???#..?#?????#??? 4,1,5,1,2\n??#?...#?? 4,1\n??????.#?#?##??.?? 2,7\n.???????##???. 1,9\n?..#.????#??#???#?? 1,3,9\n?#??????????#???.#?? 4,3,1,1,3\n.?????#???.??#?.?. 4,1\n??#.?##?#??##??#?#? 1,1,12,1\n?##??#??##???#.?.. 2,9\n#??????#??? 3,4\n##???.?#..#.?# 5,2,1,2\n???.?.???# 2,1,3\n?.?????.?? 2,2\n???.?????#?.?????? 1,2,2\n.#????#????.? 1,6\n????.#.?#??????#???? 1,1,1,1,2,7\n?.???.#.??##???#?? 1,1,1,1,8\n??????.?#? 4,2\n#??..?????#? 2,1,2,1\n?##.#.????##?# 2,1,2,4\n????????#???. 9,1\n??..????.? 1,4\n????#???#?.? 9,1\n#???.??????? 3,1,2,1\n.??????.?##??#. 6,3,1\n#.?.?#????#??#? 1,2,1,2,2\n##??##?.??? 6,1\n?????.????#???? 1,1,6" <> ...}
23
+
```
24
+
25
+
```elixir
26
+
defmodule Day12 do
27
+
def parse_pattern(pattern) do
28
+
pattern
29
+
|> String.to_charlist()
30
+
|> Enum.map(&symbol_to_type/1)
31
+
|> do_chunking()
32
+
|> Enum.chunk_by(&(elem(&1, 0) == :gap))
33
+
|> Enum.reject(&match?([{:gap, _}], &1))
34
+
end
35
+
36
+
defp do_chunking([start | rest]), do: do_chunking(start, rest, 1)
37
+
38
+
defp do_chunking(curr, [], acc), do: [{curr, acc}]
39
+
defp do_chunking(curr, [curr | rest], acc), do: do_chunking(curr, rest, acc + 1)
40
+
defp do_chunking(curr, [next | rest], acc), do: [{curr, acc} | do_chunking(next, rest, 1)]
41
+
42
+
defp symbol_to_type(?.), do: :gap
43
+
defp symbol_to_type(??), do: :wild
44
+
defp symbol_to_type(?#), do: :lava
45
+
end
46
+
```
47
+
48
+
<!-- livebook:{"output":true} -->
49
+
50
+
```
51
+
{:module, Day12, <<70, 79, 82, 49, 0, 0, 10, ...>>, {:symbol_to_type, 1}}
52
+
```
53
+
54
+
```elixir
55
+
puzzles =
56
+
puzzle_input
57
+
|> String.split("\n", trim: true)
58
+
|> Enum.map(fn line ->
59
+
[pattern, values] = String.split(line)
60
+
values = values |> String.split(",") |> Enum.map(&String.to_integer/1)
61
+
62
+
{Day12.parse_pattern(pattern), values}
63
+
end)
64
+
```
65
+
66
+
<!-- livebook:{"output":true} -->
67
+
68
+
```
69
+
[
70
+
{[[lava: 1, wild: 2], [lava: 1, wild: 2], [wild: 1]], [3, 1, 1, 1]},
71
+
{[[wild: 3], [lava: 2, wild: 2, lava: 1, wild: 6, lava: 1, wild: 3, lava: 1]], [1, 13, 1]},
72
+
{[[wild: 2, lava: 1], [wild: 1, lava: 1, wild: 2, lava: 1, wild: 4, lava: 1, wild: 2]],
73
+
[2, 4, 1, 1, 1]},
74
+
{[
75
+
[wild: 3, lava: 1, wild: 2, lava: 1],
76
+
[wild: 3, lava: 1],
77
+
[wild: 1, lava: 1, wild: 2, lava: 1, wild: 1, lava: 1]
78
+
], [4, 2, 1, 2, 1, 4]},
79
+
{[[wild: 4, lava: 1, wild: 1, lava: 2, wild: 3, lava: 1], [wild: 2], [wild: 1]], [2, 2, 6, 1]},
80
+
{[[wild: 5, lava: 1, wild: 3], [lava: 3], [lava: 2, wild: 1]], [7, 3, 2]},
81
+
{[[lava: 3, wild: 1], [lava: 1, wild: 6, lava: 1, wild: 4]], [4, 8, 1]},
82
+
{[[wild: 15]], [1, 1, 1, 2, 1]},
83
+
{[[wild: 3], [wild: 8, lava: 1, wild: 1]], [1, 3, 1, 1]},
84
+
{[
85
+
[wild: 3],
86
+
[lava: 1],
87
+
[wild: 1, lava: 1],
88
+
[wild: 1, lava: 1, wild: 1, lava: 1, wild: 2, lava: 1, wild: 1]
89
+
], [2, 1, 1, 5, 1]},
90
+
{[[wild: 1], [wild: 2, lava: 1], [wild: 4]], [1, 3, 1, 2]},
91
+
{[[lava: 1, wild: 1], [wild: 2, lava: 1, wild: 5, lava: 2], [lava: 1]], [1, 2, 1, 3, 1]},
92
+
{[[wild: 1, lava: 3, wild: 4], [lava: 1, wild: 2]], [5, 1, 2]},
93
+
{[[wild: 1, lava: 1, wild: 2], [wild: 5]], [2, 4]},
94
+
{[[wild: 1], [lava: 1, wild: 4, lava: 1, wild: 5, lava: 1, wild: 2, lava: 1, wild: 2]],
95
+
[1, 6, 1, 4, 1]},
96
+
{[[lava: 1, wild: 8, lava: 1, wild: 1, lava: 1, wild: 2]], [1, 7, 1, 1]},
97
+
{[[wild: 1, lava: 1, wild: 2], [wild: 6]], [3, 1, 1]},
98
+
{[[wild: 1], [wild: 2, lava: 1, wild: 1, lava: 3, wild: 2]], [1, 6]},
99
+
{[[wild: 3], [wild: 1], [wild: 2, lava: 1, wild: 2, lava: 2, wild: 2]], [1, 1, 1, 5, 1]},
100
+
{[[lava: 1, wild: 3, lava: 1], [wild: 6]], [2, 1, 3, 1]},
101
+
{[[wild: 1, lava: 3, wild: 2], [wild: 2], [wild: 1, lava: 1, wild: 3], [wild: 1]],
102
+
[4, 1, 2, 1, 1, 1]},
103
+
{[[wild: 1], [lava: 1, wild: 3, lava: 1, wild: 1], [wild: 2]], [2, 1, 1]},
104
+
{[[lava: 1, wild: 2, lava: 2, wild: 4, lava: 2, wild: 6, lava: 1, wild: 1]], [7, 5, 2]},
105
+
{[[wild: 4, lava: 1, wild: 12, lava: 1]], [1, 6, 1, 1, 2]},
106
+
{[[lava: 1, wild: 1], [wild: 1], [lava: 2, wild: 4]], [1, 1, 5]},
107
+
{[[wild: 5], [wild: 1, lava: 1, wild: 8]], [1, 2, 2, 2, 1]},
108
+
{[[lava: 1, wild: 2], [wild: 3, lava: 1, wild: 1], [wild: 5]], [2, 5, 1, 1]},
109
+
{[[wild: 9], [lava: 1, wild: 3]], [6, 2]},
110
+
{[[wild: 10]], [1, 1, 4]},
111
+
{[[wild: 1, lava: 1, wild: 2, lava: 1, wild: 2, lava: 1, wild: 1, lava: 2]], [1, 7]},
112
+
{[[wild: 4, lava: 1, wild: 1, lava: 2, wild: 3, lava: 1, wild: 1]], [1, 6, 1, 1]},
113
+
{[[wild: 2, lava: 1, wild: 2, lava: 1], [wild: 3, lava: 1, wild: 6]], [1, 1, 1, 7, 1]},
114
+
{[[wild: 5, lava: 2, wild: 1], [wild: 1, lava: 1, wild: 2]], [1, 2, 4]},
115
+
{[[wild: 3, lava: 2, wild: 4, lava: 3, wild: 4]], [4, 7]},
116
+
{[[wild: 1], [wild: 1], [wild: 1], [wild: 1, lava: 1, wild: 4]], [1, 1, 6]},
117
+
{[[wild: 3], [wild: 2], [wild: 4], [lava: 3, wild: 2]], [2, 2, 2, 5]},
118
+
{[[wild: 4, lava: 2, wild: 2, lava: 1, wild: 5]], [1, 7, 1, 1]},
119
+
{[[wild: 3], [wild: 4, lava: 1, wild: 3]], [2, 6]},
120
+
{[[wild: 2], [wild: 8]], [1, 2]},
121
+
{[[wild: 1], [lava: 1, wild: 1], [wild: 5]], [1, 2]},
122
+
{[[wild: 6], [lava: 1, wild: 3, lava: 1, wild: 1]], [2, 5]},
123
+
{[[wild: 5, lava: 1], [lava: 3, wild: 3, lava: 1], [wild: 3, lava: 1]], [6, 7, 1, 1]},
124
+
{[[lava: 2], [wild: 4, lava: 2], [lava: 1, wild: 2, lava: 1, ...]], [2, 6, 1, 1]},
125
+
{[[wild: 5], [wild: 2], [wild: 9]], [1, 6]},
126
+
{[[wild: 6], [lava: 1, wild: 1, ...]], [4, 3]},
127
+
{[[lava: 1, wild: 6, ...], [wild: 1, ...]], [10, 2]},
128
+
{[[wild: 1], [...], ...], [1, ...]},
129
+
{[[...]], [...]},
130
+
{[...], ...},
131
+
{...},
132
+
...
133
+
]
134
+
```
135
+
136
+
## Part 1
137
+
138
+
```elixir
139
+
defmodule Day12.Part1 do
140
+
def count_combinations([], []), do: 1
141
+
def count_combinations([[{:lava, lava} | _] | _], [segment | _]) when lava > segment, do: 0
142
+
def count_combinations(chunks, segments) when length(chunks) > length(segments), do: 0
143
+
144
+
def count_combinations([chunk | rest], [segment | srest]) do
145
+
chunk_length = chunk_length(chunk)
146
+
147
+
cond do
148
+
chunk_length < segment ->
149
+
0
150
+
151
+
chunk_length == segment ->
152
+
count_combinations(rest, srest) + 1
153
+
154
+
true ->
155
+
raise "Unimplemented"
156
+
end
157
+
end
158
+
159
+
defp chunk_length(list), do: Enum.reduce(list, 0, fn {_, val}, acc -> acc + val end)
160
+
161
+
defp chunk_splits(remaining, 0), do: {1, [remaining]}
162
+
defp chunk_splits([], segment) when segment > 0, do: {0, []}
163
+
defp chunk_splits([{:lava, n} | rest], segment), do: chunk_splits(rest, segment - n)
164
+
end
165
+
```
166
+
167
+
<!-- livebook:{"output":true} -->
168
+
169
+
```
170
+
warning: variable "rest" is unused (if the variable is not meant to be used, prefix it with an underscore)
171
+
2023/day12.livemd#cell:h2soewijh5haeddpkqukqr3fug26rvi6:6: Day12.Part1.count_combinations/2
172
+
173
+
warning: variable "srest" is unused (if the variable is not meant to be used, prefix it with an underscore)
174
+
2023/day12.livemd#cell:h2soewijh5haeddpkqukqr3fug26rvi6:6: Day12.Part1.count_combinations/2
175
+
176
+
```
177
+
178
+
<!-- livebook:{"output":true} -->
179
+
180
+
```
181
+
{:module, Day12.Part1, <<70, 79, 82, 49, 0, 0, 9, ...>>, {:chunk_length, 1}}
182
+
```
183
+
184
+
<!-- livebook:{"offset":10867,"stamp":{"token":"XCP.pErJuFAGcK1hyBg5n9FHQQCOc5uSp_xseil4UKha7AOJ2dF-diuCgS0T9sDTdi3bmDpRyQ3_9AYatfSZ6gVmYo8z2aHjDHdLDSoMb7a-ccykpMXbZIu3HqQdRGPO_mU6Fw","version":2}} -->
+303
2023/day13.livemd
+303
2023/day13.livemd
···
1
+
<!-- livebook:{"persist_outputs":true} -->
2
+
3
+
# Day 13
4
+
5
+
```elixir
6
+
Mix.install([:kino_aoc])
7
+
```
8
+
9
+
## Setup
10
+
11
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"13","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", "13", 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#.#.###\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##.#...#.\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#.##.###......#\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...#.###.#.\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..........##...\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.#..#.#\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...##.#..\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..####.#.#.####.#\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.####...##.#..#.#\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
+
"""
28
+
#.##..##.
29
+
..#.##.#.
30
+
##......#
31
+
##......#
32
+
..#.##.#.
33
+
..##..##.
34
+
#.#.##.#.
35
+
36
+
#...##..#
37
+
#....#..#
38
+
..##..###
39
+
#####.##.
40
+
#####.##.
41
+
..##..###
42
+
#....#..#
43
+
"""
44
+
```
45
+
46
+
<!-- livebook:{"output":true} -->
47
+
48
+
```
49
+
"#.##..##.\n..#.##.#.\n##......#\n##......#\n..#.##.#.\n..##..##.\n#.#.##.#.\n\n#...##..#\n#....#..#\n..##..###\n#####.##.\n#####.##.\n..##..###\n#....#..#\n"
50
+
```
51
+
52
+
```elixir
53
+
defmodule Day13 do
54
+
def find_axes(list) do
55
+
reversed = Enum.reverse(list)
56
+
57
+
len = length(list)
58
+
59
+
back = dbg(do_find(list, 0))
60
+
front = dbg(do_find(reversed, 0))
61
+
62
+
[
63
+
if(back, do: div(len - back, 2) + back),
64
+
if(front, do: div(len - front, 2))
65
+
]
66
+
|> Enum.filter(& &1)
67
+
end
68
+
69
+
defp do_find([_], _), do: nil
70
+
71
+
defp do_find([_ | a], n) when rem(n, 2) == 0, do: do_find(a, n + 1)
72
+
73
+
defp do_find(a, n) do
74
+
if palindrome?(a) do
75
+
n
76
+
else
77
+
do_find(tl(a), n + 1)
78
+
end
79
+
end
80
+
81
+
def palindrome?(list) do
82
+
list == Enum.reverse(list)
83
+
end
84
+
85
+
def print_mirror({rows, cols, _, _}) do
86
+
width = length(cols)
87
+
88
+
display =
89
+
for row <- rows do
90
+
for digit <- Integer.digits(row, 2) do
91
+
if digit == 1, do: "#", else: "."
92
+
end
93
+
|> List.to_string()
94
+
|> String.pad_leading(width, ".")
95
+
end
96
+
97
+
IO.puts(Enum.intersperse(display, "\n"))
98
+
end
99
+
end
100
+
```
101
+
102
+
<!-- livebook:{"output":true} -->
103
+
104
+
```
105
+
{:module, Day13, <<70, 79, 82, 49, 0, 0, 20, ...>>, {:print_mirror, 1}}
106
+
```
107
+
108
+
```elixir
109
+
mirrors =
110
+
puzzle_input
111
+
|> String.split("\n\n", trim: true)
112
+
|> Enum.map(fn grid ->
113
+
mirror =
114
+
grid
115
+
|> String.split("\n", trim: true)
116
+
|> Enum.map(fn line ->
117
+
for <<c <- line>>, do: if(c == ?#, do: 1, else: 0)
118
+
end)
119
+
120
+
rows = Enum.map(mirror, &Integer.undigits(&1, 2))
121
+
cols = Enum.zip_with(mirror, &Integer.undigits(&1, 2))
122
+
123
+
row = Day13.find_axes(rows)
124
+
col = Day13.find_axes(cols)
125
+
126
+
{rows, cols, row, col}
127
+
end)
128
+
```
129
+
130
+
<!-- livebook:{"output":true} -->
131
+
132
+
```
133
+
[
134
+
{[576, 320, 272, 1423, 591, 1391, 1833], [11, 69, 59, 8, 102, 3, 16, 15, 14, 14, 15], [], ~c"\t"},
135
+
{[727, 486, 2044, 819, 819, 2044, 486, 727, 1325, 503, 193, 292, 196],
136
+
[1168, 6048, 4058, 7405, 7405, 4058, 6056, 1168, 7419, 7016, 4924], [4], []},
137
+
{[26, 71, 71, 27, 18, 6, 84, 35, 104, 119, 119, 104, 35],
138
+
[3166, 63, 4940, 4626, 3276, 8109, 3629], ~c"\n", []},
139
+
{[87, 27, 15, 97, 97, 15, 27, 87, 95, 6, 34, 95, 67, 77, 77, 75, 95],
140
+
[78655, 12352, 100129, 52527, 84909, 118771, 130879], [4], []},
141
+
{[28948, 11524, 7312, 7312, 11520, 28948, 29291],
142
+
[67, 103, 91, 60, 60, 1, 102, 24, 1, 1, 90, 1, 98, 1, 1], [], [14]},
143
+
{[416, 418, 83, 97, 289, 332, 332, 289, 97, 83, 418, 416, 330],
144
+
[6631, 6150, 1753, 6966, 1032, 193, 192, 3085, 1848], [6], []},
145
+
{[4683, 7, 7, 4683, 7229, 385, 6553, 7228, 387, 2069, 3123, 1441, 7806, 3255, 1634],
146
+
[19844, 1462, 1183, 18437, 840, 842, 18437, 1183, 1462, 19844, 13478, 30807, 32634], [2], []},
147
+
{[370, 1952, 364, 197, 1856, 2039, 327, 1910, 1827, 1562, 1931, 448, 916, 1738, 1738],
148
+
[9971, 9975, 30684, 10783, 24459, 29376, 17060, 4147, 7044, 17395, 2896], [14], []},
149
+
{[23425, 9523, 6472, 17236, 17278, 32285, 23094, 6647, 6649, 6649, 6647, 23094, 32285, 17278,
150
+
17172],
151
+
[20239, 8708, 21500, 21500, 8708, 20239, 31987, 16624, 7410, 9722, 12287, 5734, 3999, 9626,
152
+
25332], [], [3]},
153
+
{[264, 15458, 32359, 32359, 408, 15867, 9722],
154
+
[24, 59, 58, 58, 59, 24, 71, 7, 59, 59, 7, 71, 24, 59, 26], [], [3]},
155
+
{[131059, 65309, 65301, 91878, 23060, 16956, 82644, 33027, 33027, 82646, 16956],
156
+
[1170, 1804, 2035, 1920, 1856, 1856, 1920, 2035, 1804, 1170, 1170, 1185, 1907, 545, 1011, 1166,
157
+
1804], [], [5]},
158
+
{[186, 107, 407, 407, 107, 186, 1364, 211, 753, 689, 211, 1364, 186, 107, 407],
159
+
[264, 96, 6409, 23285, 9690, 26214, 23549, 26118, 6409, 32407, 15603], [3], []},
160
+
{[11602, 63, 29650, 28032, 4705, 11550, 24734, 7756, 24972],
161
+
[101, 365, 82, 298, 298, 82, 361, 101, 338, 144, 460, 143, 143, 460, 144], [], ~c"\f"},
162
+
{[1980, 10172, 22140, 25983, 11116, 6500, 30788, 5172, 18740, 8239, 24, 16875, 24967, 735, 9604,
163
+
16836, 17152],
164
+
[25907, 46228, 19968, 7424, 123396, 118793, 112951, 98366, 31786, 129952, 123720, 127208, 130974,
165
+
8376, 8376], [], [14]},
166
+
{[19591, 18951, 632, 14023, 883, 13066, 12628],
167
+
[96, 11, 11, 96, 72, 62, 7, 72, 29, 20, 21, 18, 105, 110, 108], [], [2]},
168
+
{[899, 258, 495, 1418, 1167, 1703, 1703, 1167, 1418, 495, 258, 899, 722, 284, 284, 658, 899],
169
+
[16128, 68659, 123373, 98227, 16528, 19584, 30, 29580, 24204, 131059, 89761], [6], []},
170
+
{[115, 15, 37, 88, 68, 68, 88], ~c"OPI)6`p", [5], []},
171
+
{[4128, 20521, 10128, 10326, 8166, 6048, 7398, 20431, 16118, 18505, 24601, 774, 13488],
172
+
[2092, 1557, 6609, 888, 1521, 1458, 1442, 1521, 888, 6609, 1557, 2092, 882, 882, 2092], [],
173
+
~c"\r"},
174
+
{~c"\v\bOO\b\v]5.62.5", [1600, 63, 109, 8146, 1659, 5790, 5857], [3], []},
175
+
{[70, 115, 52, 470, 102, 462, 84, 484, 62, 444, 467, 127, 127, 465, 444, 62, 484],
176
+
[10957, 10957, 114297, 54199, 58878, 2486, 98231, 113010, 32888], [], [1]},
177
+
{[198, 306, 463, 310, 204, 315, 219, 27, 217, 216, 216, 217, 27],
178
+
[3712, 5470, 5470, 2688, 2815, 1535, 5888, 7905, 1267], ~c"\n", []},
179
+
{[71371, 104223, 104221, 71371, 8422, 31421, 31421, 8422, 71371],
180
+
[481, 192, 12, 30, 493, 12, 481, 493, 192, 319, 307, 30, 204, 493, 222, 435, 493], [6], []},
181
+
{[13279, 13278, 13719, 19445, 8600, 26086, 518, 26199, 3242, 2488, 2488],
182
+
[168, 1896, 1792, 135, 300, 1688, 2019, 2023, 1704, 167, 1995, 1607, 1976, 1852, 1416], ~c"\n",
183
+
[]},
184
+
{[1237, 2022, 1161, 1161, 2022, 1237, 1177, 1131, 2029, 79, 1946],
185
+
[2045, 581, 581, 2037, 1646, 588, 1073, 415, 1638, 587, 1470], [3], []},
186
+
{[111450, 7065, 54910, 54910, 7065, 111450, 127548, 25051, 61861, 61569, 102656, 53858, 127683,
187
+
87229, 114432],
188
+
[17175, 23421, 6638, 17381, 32639, 9217, 6147, 32525, 26321, 9446, 23180, 6474, 32642, 32642,
189
+
6466, 23180, 9446], [3], []},
190
+
{[20, 22, 436, 394, 359, 359, 394], [31, 25, 6, 22, 112, 9, 118, 47, 6], [5], []},
191
+
{[100217, 100217, 46111, 64677, 64959, 18555, 64861, 131030, 388, 112431, 66318, 67525, 118470],
192
+
[6191, 8041, 993, 1896, 1896, 993, 8043, 6191, 6526, 819, 6371, 7048, 7648, 7628, 1919, 1453,
193
+
8138], [1], []},
194
+
{[291, 1, 24, 28, 1, 291, 492], [67, 1, 1, 67, 24, 25, 9, 66, 102], [], [2]},
195
+
{~c"2aa2\n}|\n2", [204, 493, 301, 30, 12, 307, 200], [2], []},
196
+
{[3115, 4616, 3100, 4656, 4643, 1344, 167], [44, 80, 82, 44, 2, 1, 2, 77, 24, 112, 17, 69, 69],
197
+
[], ~c"\f"},
198
+
{[67339, 92194, 8007, 70176, 4382, 5406, 70176, 8007, 92194, 67339, 55372, 10833, 123746, 57569,
199
+
57569],
200
+
[26980, 23, 8279, 8271, 8080, 12504, 21152, 22956, 22180, 3, 4255, 10567, 1544, 17968, 5776,
201
+
30436, 20651], [14], []},
202
+
{[6424, 26178, 346, 6490, 23485, 15384, 14592, 9703, 26392, 23515, 32280, 32475, 15706, 32358,
203
+
9471, 23320, 17254],
204
+
[37355, 36732, 81146, 81146, 35708, 37355, 96147, 4772, 58045, 4621, 96758, 96758, 4621, 58045,
205
+
4772], [], ~c"\v"},
206
+
{[75457, 7450, 103542, 100685, 20575, 20575, 117069, 103542, 7450, 75457, 75457, 7450, 103542,
207
+
117069, 20575],
208
+
[22966, 6534, 1795, 16432, 14029, 10570, 28924, 16432, 10570, 16432, 24503, 4228, 14029, 12107,
209
+
8071, ...], ~c"\n", []},
210
+
{[114654, 1118, 92031, 101299, 101299, 92031, 1118, 114654, 31935, 80545, 20702, 1480, 17953,
211
+
69836, 60269, ...],
212
+
[96904, 78341, 18775, 84868, 66504, 78725, 118578, 96919, 96805, 78826, 118382, 31124, 130880,
213
+
118637, ...], [4], []},
214
+
{[14474, 14474, 17870, 27951, 39, 7069, 240, 31399, 31655, 240, 7069],
215
+
[396, 1676, 1581, 1709, 384, 45, 421, 1855, 274, 222, 51, 1953, 493, ...], [1], []},
216
+
{[36, 36, 84, 53, 75, 28, 32, 126, 125, 125, 126, 36, 28, ...],
217
+
[5362, 27129, 6901, 1782, 31485, 1170, 3171], [1], []},
218
+
{[4259, 8068, 7, 8168, 4551, 6595, 1584, 4292, 84],
219
+
[442, 168, 164, 164, 184, 442, 59, 292, 5, 32, 211, ...], [], ~c"\f"},
220
+
{[130987, 86, 74905, 93, 126, 56186, 81145, 81094, 23097, 81025, 124915, ...],
221
+
[20924, 16916, 16980, 20924, 17386, 17386, 20924, 16980, 16916, 20924, ...], [], [5]},
222
+
{[38804, 125056, 92872, 151, 1196, 129732, 62279], [50, 99, 51, 51, 67, 50, 68, 83, 65, ...], [],
223
+
[16]},
224
+
{[54, 11, 393, 54, 127, 127, 54, 393, 11, ...],
225
+
[1056, 1057, 388, 5069, 5071, 3510, 5066, 7130, ...], [5], []},
226
+
{[391, 2025, 404, 2039, 188, 1629, 1605, 1894, ...],
227
+
[44902, 44902, 123750, 127129, 44866, 45628, 31078, ...], [], [1]},
228
+
{[1658, 1655, 26, 2019, 1637, 1649, 1655, ...], [446, 444, 34, 34, 444, 446, ...], [], [3]},
229
+
{[365, 1438, 1069, 780, 1216, 1664, ...], [14332, 2892, 27071, 10003, 17863, ...], [14], []},
230
+
{[7917, 64, 436, 297, 7982, ...], [70857, 70889, 70889, 70857, ...], [], [2]},
231
+
{[7224, 12736, 21104, 27923, ...], [32323, 42255, 121795, ...], [5], []},
232
+
{[203, 313, 1753, ...], [5527, 5527, ...], [], [...]},
233
+
{[41, 73, ...], [685, ...], [], ...},
234
+
{[116426, ...], [...], ...},
235
+
{[...], ...},
236
+
{...},
237
+
...
238
+
]
239
+
```
240
+
241
+
## Part 1
242
+
243
+
```elixir
244
+
Enum.map(mirrors, fn {_, _, row, col} ->
245
+
List.first(col, 0) + List.first(row, 0) * 100
246
+
end)
247
+
|> Enum.sum()
248
+
```
249
+
250
+
<!-- livebook:{"output":true} -->
251
+
252
+
```
253
+
40006
254
+
```
255
+
256
+
## Part 2
257
+
258
+
```elixir
259
+
defmodule Day13.Part2 do
260
+
import Bitwise
261
+
262
+
def alternatives(list, a, n) do
263
+
l = length(list)
264
+
265
+
list =
266
+
for i <- 0..n,
267
+
d = bsl(1, i),
268
+
j <- 0..l,
269
+
desmudged = List.update_at(list, j, &bxor(&1, d)),
270
+
v <- Day13.find_axes(desmudged),
271
+
v not in a,
272
+
do: v
273
+
274
+
Enum.dedup(list)
275
+
end
276
+
end
277
+
```
278
+
279
+
<!-- livebook:{"output":true} -->
280
+
281
+
```
282
+
{:module, Day13.Part2, <<70, 79, 82, 49, 0, 0, 11, ...>>, {:alternatives, 3}}
283
+
```
284
+
285
+
```elixir
286
+
mirrors
287
+
|> Enum.with_index()
288
+
|> Enum.map(fn {{rows, cols, row, col}, _idx} ->
289
+
row = List.first(Day13.Part2.alternatives(rows, row, length(cols)), 0)
290
+
col = List.first(Day13.Part2.alternatives(cols, col, length(rows)), 0)
291
+
292
+
row * 100 + col
293
+
end)
294
+
|> Enum.sum()
295
+
```
296
+
297
+
<!-- livebook:{"output":true} -->
298
+
299
+
```
300
+
28627
301
+
```
302
+
303
+
<!-- livebook:{"offset":14833,"stamp":{"token":"XCP.8-i47duAdnzdKS-qi8IVDyDE21kJUyqTX55xsBPltOjjVtrJUuw2vu5-Ufhj9sPB_IGriiYKDwSN8h0k2cz2-dY78-3ZRE77glupVo5cCwEbWm4pbp6TLRefkSB06zCZdQ","version":2}} -->