tangled
alpha
login
or
join now
hauleth.dev
/
advent-of-code
3
fork
atom
this repo has no description
3
fork
atom
overview
issues
pulls
pipelines
Fight with day 5 continues
hauleth.dev
2 years ago
4b718428
6cf9b5f0
verified
This commit was signed with the committer's
known signature
.
hauleth.dev
SSH Key Fingerprint:
SHA256:1hEP8QO8nM2KQfQ8jK4Q19y/CmqVZQI/cNSht3c1QlI=
+443
1 changed file
expand all
collapse all
unified
split
2023
day05.livemd
+443
2023/day05.livemd
···
1
1
+
<!-- livebook:{"persist_outputs":true} -->
2
2
+
3
3
+
# Day 05
4
4
+
5
5
+
```elixir
6
6
+
Mix.install([:kino_aoc, {:range_set, path: "../range_set"}])
7
7
+
```
8
8
+
9
9
+
## Parse
10
10
+
11
11
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"5","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
12
12
+
13
13
+
```elixir
14
14
+
{:ok, puzzle_input} =
15
15
+
KinoAOC.download_puzzle("2023", "5", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
16
16
+
```
17
17
+
18
18
+
<!-- livebook:{"output":true} -->
19
19
+
20
20
+
```
21
21
+
{:ok,
22
22
+
"seeds: 1310704671 312415190 1034820096 106131293 682397438 30365957 2858337556 1183890307 665754577 13162298 2687187253 74991378 1782124901 3190497 208902075 226221606 4116455504 87808390 2403629707 66592398\n\nseed-to-soil map:\n2879792625 0 201678008\n2425309256 1035790247 296756276\n2722065532 1759457739 157727093\n400354950 1917184832 1164285801\n0 201678008 400354950\n1564640751 602032958 433757289\n1998398040 1332546523 426911216\n\nsoil-to-fertilizer map:\n3434127746 3670736129 29685965\n1809924203 1168707872 308179\n2108903682 1437989162 44479258\n237181023 2915565442 27901445\n1173998623 2434447796 13633544\n75539025 740516241 29278225\n41104738 706081954 34434287\n3279397405 3488165796 12149874\n3463813711 3827946213 157129363\n1810232382 769794466 15695437\n877824710 677909236 28172718\n2215709448 1746651561 307558709\n1825927819 1692597620 54053941\n104817250 420198730 132363773\n2916210208 392942051 27256679\n1022591555 2448081340 151407068\n3925105941 3985075576 182313682\n1897186025 2212065968 211717657\n2198981202 1304666789 16728246\n850656807 2054210270 27167903\n3766599721 3500315670 158506220\n3419071398 3279397405 15056348\n7830088 2126976435 33274650\n3620943074 3658821890 11914239\n1264213180 2599488408 138420934\n811586355 2160251085 12020898\n3632857313 3354423388 133742408\n1612763314 1169016051 108601184\n1721364498 2172271983 39793985\n1187632167 601328223 76581013\n823607253 1277617235 27049554\n728944387 2737909342 82641968\n0 2426617708 7830088\n3291547279 3700422094 127524119\n1402634114 1482468420 210129200\n905997428 1321395035 107714902\n4107419623 3294453753 59969635\n1879981760 785489903 17204265\n2153382940 2081378173 45598262\n277361019 802694168 366013704\n1761158483 552562503 48765720\n646208806 2832829861 82735581\n2523268157 0 392942051\n1013712330 1429109937 8879225\n643374723 2423783625 2834083\n265082468 2820551310 12278551\n\nfertilizer-to-water map:\n4253122607 1473424614 41844689\n3040447798 2659805568 46237011\n0 146022665 42081460\n55436822 188104125 65067713\n42081460 132667303 13355362\n2429043181 3587614447 54605699\n888256662 672288214 24436041\n4064969883 1978094070 95324589\n3086684809 977403736 339965972\n120504535 253171838 93494065\n2810558403 2603914183 55891385\n3898695123 2901215107 166274760\n2483648880 4002918707 103777141\n1300545784 2848997109 52217998\n2418717938 1463099371 10325243\n1022681665 808998429 30429585\n2866449788 1411682577 4750813\n1181605510 4172708724 118940274\n2078503930 2466708865 42530000\n1105548530 1545561518 76056980\n978705579 2573458117 30456066\n2324405069 1317369708 94312869\n1991848966 3429793336 22435712\n4190586687 2706042579 43180396\n1352763782 1416433390 46665981\n3760606255 1683093685 138088868\n1399429763 3452229048 135385399\n2121033930 839428014 137975722\n2940673664 2749222975 99774134\n1053111250 2073418659 52437280\n3426650781 1821182553 152991287\n1534815162 2195329002 252024339\n730962658 3067489867 157294004\n3579642068 710244275 98754154\n1786839501 3224783871 205009465\n2259009652 1974173840 3920230\n2587426021 370264097 223132382\n2871200601 2125855939 69473063\n213998600 44701447 87965856\n4233767083 2447353341 19355524\n2262929882 1621618498 61475187\n1009161645 696724255 13520020\n3678396222 593396479 78891735\n912692703 4106695848 66012876\n3757287957 4291648998 3318298\n301964456 0 44701447\n2014284678 2509238865 64219252\n370264097 3642220146 360698561\n4160294472 1515269303 30292215\n\nwater-to-light map:\n4066036887 2992193346 95912236\n531075515 493316918 162009008\n3260565192 854248031 437396028\n1341316194 4205924684 89042612\n1879858967 2058162578 692895326\n452475911 655325926 78599604\n2997176790 1690328655 208783332\n2731804884 3324847814 265371906\n355611136 0 96864775\n2572754293 1899111987 159050591\n1081338600 3590219720 138271571\n1430358806 2779435417 212757929\n3234337635 4179697127 26227557\n854248031 3728491291 227090569\n4161949123 3955581860 102409244\n3205960122 2751057904 28377513\n50952557 147817332 304658579\n1219610171 4057991104 121706023\n4264358367 1291644059 30608929\n3697961220 1322252988 368075667\n1643116735 3088105582 236742232\n693084523 452475911 40841007\n0 96864775 50952557\n\nlight-to-temperature ma" <> ...}
23
23
+
```
24
24
+
25
25
+
```elixir
26
26
+
puzzle_input =
27
27
+
"""
28
28
+
seeds: 79 14 55 13
29
29
+
30
30
+
seed-to-soil map:
31
31
+
50 98 2
32
32
+
52 50 48
33
33
+
34
34
+
soil-to-fertilizer map:
35
35
+
0 15 37
36
36
+
37 52 2
37
37
+
39 0 15
38
38
+
39
39
+
fertilizer-to-water map:
40
40
+
49 53 8
41
41
+
0 11 42
42
42
+
42 0 7
43
43
+
57 7 4
44
44
+
45
45
+
water-to-light map:
46
46
+
88 18 7
47
47
+
18 25 70
48
48
+
49
49
+
light-to-temperature map:
50
50
+
45 77 23
51
51
+
81 45 19
52
52
+
68 64 13
53
53
+
54
54
+
temperature-to-humidity map:
55
55
+
0 69 1
56
56
+
1 0 69
57
57
+
58
58
+
humidity-to-location map:
59
59
+
60 56 37
60
60
+
56 93 4
61
61
+
"""
62
62
+
|> String.trim()
63
63
+
```
64
64
+
65
65
+
<!-- livebook:{"output":true} -->
66
66
+
67
67
+
```
68
68
+
"seeds: 79 14 55 13\n\nseed-to-soil map:\n50 98 2\n52 50 48\n\nsoil-to-fertilizer map:\n0 15 37\n37 52 2\n39 0 15\n\nfertilizer-to-water map:\n49 53 8\n0 11 42\n42 0 7\n57 7 4\n\nwater-to-light map:\n88 18 7\n18 25 70\n\nlight-to-temperature map:\n45 77 23\n81 45 19\n68 64 13\n\ntemperature-to-humidity map:\n0 69 1\n1 0 69\n\nhumidity-to-location map:\n60 56 37\n56 93 4"
69
69
+
```
70
70
+
71
71
+
```elixir
72
72
+
defmodule Mapping do
73
73
+
@behaviour Access
74
74
+
75
75
+
defstruct [:values]
76
76
+
77
77
+
def from_list(lst) do
78
78
+
# true = Enum.all?(lst, fn {a, b} -> Range.size(a) == Range.size(b) end)
79
79
+
%__MODULE__{values: Enum.sort(lst)}
80
80
+
end
81
81
+
82
82
+
def squash(%__MODULE__{values: from}, %__MODULE__{values: to}) do
83
83
+
from_list(do_squash(from, to))
84
84
+
end
85
85
+
86
86
+
defp do_squash([], rest), do: rest
87
87
+
defp do_squash(rest, []), do: rest
88
88
+
89
89
+
# a---b
90
90
+
# c---d
91
91
+
defp do_squash([{_src, a.._b} | _] = xs, [{_c..d, _out} = v | ys]) when d < a do
92
92
+
[v | do_squash(xs, ys)]
93
93
+
end
94
94
+
95
95
+
# a---b
96
96
+
# c---d
97
97
+
defp do_squash([{_src, _a..b} = v | xs], [{c.._d, _out} | _] = ys) when b < c do
98
98
+
[v | do_squash(xs, ys)]
99
99
+
end
100
100
+
101
101
+
# a---b
102
102
+
# c---d
103
103
+
defp do_squash([{src, range} | xs], [{range, out} | ys]) do
104
104
+
[{src, out} | do_squash(xs, ys)]
105
105
+
end
106
106
+
107
107
+
# a------b
108
108
+
# c--d
109
109
+
defp do_squash([{src, a..b} | xs], [{c..d, out} | ys]) when a <= c and b >= d do
110
110
+
range_match(src, [
111
111
+
a..(c - 1),
112
112
+
out,
113
113
+
(d + 1)..b
114
114
+
])
115
115
+
|> Enum.concat(do_squash(xs, ys))
116
116
+
end
117
117
+
118
118
+
# a--b
119
119
+
# c------d
120
120
+
defp do_squash([{src, a..b} | xs], [{c..d, out} | ys]) when a >= c and b <= d do
121
121
+
range_match(
122
122
+
[
123
123
+
c..(a - 1),
124
124
+
src,
125
125
+
(b + 1)..d
126
126
+
],
127
127
+
out
128
128
+
)
129
129
+
|> Enum.concat(do_squash(xs, ys))
130
130
+
end
131
131
+
132
132
+
# a---b
133
133
+
# c---d
134
134
+
defp do_squash([{src, a..b} | xs], [{c..d, out} | ys]) when c in a..b and b in c..d do
135
135
+
{s1, s2} = Range.split(src, Range.size(a..c) - 1)
136
136
+
{o1, o2} = Range.split(out, Range.size(c..b))
137
137
+
138
138
+
[
139
139
+
{s1, a..(c - 1)},
140
140
+
{s2, o1},
141
141
+
{(b + 1)..d, o2}
142
142
+
]
143
143
+
|> Enum.concat(do_squash(xs, ys))
144
144
+
end
145
145
+
146
146
+
# a---b
147
147
+
# c---d
148
148
+
defp do_squash([{src, a..b} | xs], [{c..d, out} | ys]) when a > c and b > d do
149
149
+
IO.puts("foo")
150
150
+
{of, ol} = Range.split(out, Range.size(c..a) - 1)
151
151
+
{sf, sl} = Range.split(src, Range.size(a..d))
152
152
+
153
153
+
[
154
154
+
{c..(a - 1), of},
155
155
+
{sf, ol},
156
156
+
{sl, (d + 1)..b}
157
157
+
]
158
158
+
|> Enum.concat(do_squash(xs, ys))
159
159
+
end
160
160
+
161
161
+
defp range_match(list, a.._) when is_list(list) do
162
162
+
Enum.reduce(list, {[], a}, fn
163
163
+
_.._//1 = range, {acc, s} ->
164
164
+
to = s + Range.size(range) - 1
165
165
+
{[{range, s..to} | acc], to + 1}
166
166
+
167
167
+
_, acc ->
168
168
+
acc
169
169
+
end)
170
170
+
|> elem(0)
171
171
+
end
172
172
+
173
173
+
defp range_match(_.._ = range, list) when is_list(list) do
174
174
+
for {a, b} <- range_match(list, range), do: {b, a}
175
175
+
end
176
176
+
177
177
+
@impl Access
178
178
+
def fetch(%__MODULE__{values: list}, key) when is_integer(key) do
179
179
+
val =
180
180
+
with {a.._, b.._} <- Enum.find(list, key, fn {range, _} -> key in range end) do
181
181
+
key - a + b
182
182
+
end
183
183
+
184
184
+
{:ok, val}
185
185
+
end
186
186
+
end
187
187
+
188
188
+
[seeds | maps] =
189
189
+
puzzle_input
190
190
+
|> String.split("\n\n", trim: true)
191
191
+
192
192
+
mappings =
193
193
+
maps
194
194
+
|> Enum.map(fn map ->
195
195
+
[_ | lines] = String.split(map, "\n")
196
196
+
197
197
+
lines
198
198
+
|> Enum.map(&String.split/1)
199
199
+
|> Enum.map(fn line ->
200
200
+
[to, from, len] = Enum.map(line, &String.to_integer/1)
201
201
+
{from..(from + len - 1), to..(to + len - 1)}
202
202
+
end)
203
203
+
|> Mapping.from_list()
204
204
+
end)
205
205
+
206
206
+
[seed2soil, soil2fert, fert2water, water2light, light2temp, temp2hum, hum2loc] = mappings
207
207
+
208
208
+
seeds =
209
209
+
seeds
210
210
+
|> String.split()
211
211
+
|> tl()
212
212
+
|> Enum.map(&String.to_integer/1)
213
213
+
```
214
214
+
215
215
+
<!-- livebook:{"output":true} -->
216
216
+
217
217
+
```
218
218
+
warning: function get_and_update/3 required by behaviour Access is not implemented (in module Mapping)
219
219
+
2023/day05.livemd#cell:5c3rqk2ysnul3qg2ajsq46avpmyi5ixw:1: Mapping (module)
220
220
+
221
221
+
warning: function pop/2 required by behaviour Access is not implemented (in module Mapping)
222
222
+
2023/day05.livemd#cell:5c3rqk2ysnul3qg2ajsq46avpmyi5ixw:1: Mapping (module)
223
223
+
224
224
+
```
225
225
+
226
226
+
<!-- livebook:{"output":true} -->
227
227
+
228
228
+
```
229
229
+
[79, 14, 55, 13]
230
230
+
```
231
231
+
232
232
+
```elixir
233
233
+
a = Mapping.from_list([{1..10, 31..40}])
234
234
+
b = Mapping.from_list([{25..35, 65..75}])
235
235
+
236
236
+
k = 30
237
237
+
238
238
+
dbg(b[dbg(a[k])])
239
239
+
dbg(Mapping.squash(a, b))[k]
240
240
+
```
241
241
+
242
242
+
<!-- livebook:{"output":true} -->
243
243
+
244
244
+
```
245
245
+
30
246
246
+
```
247
247
+
248
248
+
<!-- livebook:{"output":true} -->
249
249
+
250
250
+
```
251
251
+
70
252
252
+
```
253
253
+
254
254
+
<!-- livebook:{"output":true} -->
255
255
+
256
256
+
```
257
257
+
foo
258
258
+
```
259
259
+
260
260
+
<!-- livebook:{"output":true} -->
261
261
+
262
262
+
```
263
263
+
%Mapping{values: [{1..5, 71..75}, {6..10, 36..40}, {25..30, 65..70}]}
264
264
+
```
265
265
+
266
266
+
<!-- livebook:{"output":true} -->
267
267
+
268
268
+
```
269
269
+
70
270
270
+
```
271
271
+
272
272
+
## Part 1
273
273
+
274
274
+
```elixir
275
275
+
seeds
276
276
+
|> Enum.map(&Enum.reduce(mappings, &1, fn mapping, val -> mapping[val] end))
277
277
+
|> Enum.min()
278
278
+
```
279
279
+
280
280
+
<!-- livebook:{"output":true} -->
281
281
+
282
282
+
```
283
283
+
35
284
284
+
```
285
285
+
286
286
+
```elixir
287
287
+
squashed = Enum.reduce(mappings, &Mapping.squash/2)
288
288
+
```
289
289
+
290
290
+
<!-- livebook:{"output":true} -->
291
291
+
292
292
+
```
293
293
+
foo
294
294
+
foo
295
295
+
foo
296
296
+
```
297
297
+
298
298
+
<!-- livebook:{"output":true} -->
299
299
+
300
300
+
```
301
301
+
%Mapping{
302
302
+
values: [
303
303
+
{0..0, 27..27},
304
304
+
{0..5, 28..33},
305
305
+
{1..10, 40..49},
306
306
+
{6..59, 7..60},
307
307
+
{7..10, 59..62},
308
308
+
{11..14, 52..55},
309
309
+
{11..52, 0..41},
310
310
+
{15..41, 0..26},
311
311
+
{18..24, 90..96},
312
312
+
{25..55, 18..48},
313
313
+
{45..58, 74..87},
314
314
+
{49..51, 34..36},
315
315
+
{52..53, 37..38},
316
316
+
{53..60, 49..56},
317
317
+
{54..56, 56..58},
318
318
+
{56..64, 61..69},
319
319
+
{59..63, 95..99},
320
320
+
{60..80, 53..73},
321
321
+
{61..67, 63..69},
322
322
+
{64..76, 70..82},
323
323
+
{65..92, 69..96},
324
324
+
{69..69, 39..39},
325
325
+
{77..99, 45..67},
326
326
+
{81..87, 83..89},
327
327
+
{93..96, 49..52},
328
328
+
{95..97, 97..99},
329
329
+
{98..99, 50..51}
330
330
+
]
331
331
+
}
332
332
+
```
333
333
+
334
334
+
```elixir
335
335
+
seeds
336
336
+
|> Enum.map(&squashed[&1])
337
337
+
|> Enum.min()
338
338
+
```
339
339
+
340
340
+
<!-- livebook:{"output":true} -->
341
341
+
342
342
+
```
343
343
+
14
344
344
+
```
345
345
+
346
346
+
```elixir
347
347
+
Enum.map(seeds, &squashed[&1])
348
348
+
```
349
349
+
350
350
+
<!-- livebook:{"output":true} -->
351
351
+
352
352
+
```
353
353
+
[72, 15, 56, 14]
354
354
+
```
355
355
+
356
356
+
```elixir
357
357
+
seeds =
358
358
+
Enum.chunk_every(seeds, 2)
359
359
+
|> Enum.map(fn [a, b] -> a..(a + b) end)
360
360
+
|> RangeSet.new()
361
361
+
362
362
+
mappings
363
363
+
|> Enum.reduce(seeds, fn map, curr ->
364
364
+
IO.puts("")
365
365
+
IO.inspect(map, label: :map)
366
366
+
IO.inspect(curr, label: :curr)
367
367
+
inputs = RangeSet.new(for {from, _} <- map.values, do: from)
368
368
+
mapped = IO.inspect(RangeSet.intersection(inputs, curr), label: :inter)
369
369
+
left = IO.inspect(RangeSet.difference(curr, mapped), label: :diff)
370
370
+
371
371
+
mapped =
372
372
+
mapped.ranges
373
373
+
|> Enum.map(fn a..b -> map[a]..map[b]//1 end)
374
374
+
|> RangeSet.new()
375
375
+
|> IO.inspect(label: :mapped)
376
376
+
377
377
+
IO.inspect(RangeSet.union(left, mapped))
378
378
+
end)
379
379
+
```
380
380
+
381
381
+
<!-- livebook:{"output":true} -->
382
382
+
383
383
+
```
384
384
+
385
385
+
map: %Mapping{values: [{50..97, 52..99}, {98..99, 50..51}]}
386
386
+
curr: RangeSet.new([55..68, 79..93])
387
387
+
inter: RangeSet.new([55..68, 79..93])
388
388
+
diff: RangeSet.new([])
389
389
+
mapped: RangeSet.new([57..70, 81..95])
390
390
+
RangeSet.new([57..70, 81..95])
391
391
+
392
392
+
map: %Mapping{values: [{0..14, 39..53}, {15..51, 0..36}, {52..53, 37..38}]}
393
393
+
curr: RangeSet.new([57..70, 81..95])
394
394
+
inter: RangeSet.new([])
395
395
+
diff: RangeSet.new([57..70, 81..95])
396
396
+
mapped: RangeSet.new([])
397
397
+
RangeSet.new([57..70, 81..95])
398
398
+
399
399
+
map: %Mapping{
400
400
+
values: [{0..6, 42..48}, {7..10, 57..60}, {11..52, 0..41}, {53..60, 49..56}]
401
401
+
}
402
402
+
curr: RangeSet.new([57..70, 81..95])
403
403
+
inter: RangeSet.new([57..60])
404
404
+
diff: RangeSet.new([61..70, 81..95])
405
405
+
mapped: RangeSet.new([53..56])
406
406
+
RangeSet.new([53..56, 61..70, 81..95])
407
407
+
408
408
+
map: %Mapping{values: [{18..24, 88..94}, {25..94, 18..87}]}
409
409
+
curr: RangeSet.new([53..56, 61..70, 81..95])
410
410
+
inter: RangeSet.new([53..56, 61..70, 81..94])
411
411
+
diff: RangeSet.new([95..95])
412
412
+
mapped: RangeSet.new([46..49, 54..63, 74..87])
413
413
+
RangeSet.new([46..49, 54..63, 74..87, 95..95])
414
414
+
415
415
+
map: %Mapping{values: [{45..63, 81..99}, {64..76, 68..80}, {77..99, 45..67}]}
416
416
+
curr: RangeSet.new([46..49, 54..63, 74..87, 95..95])
417
417
+
inter: RangeSet.new([46..49, 54..63, 74..76, 77..87, 95..95])
418
418
+
diff: RangeSet.new([])
419
419
+
mapped: RangeSet.new([45..55, 63..63, 78..80, 82..85, 90..99])
420
420
+
RangeSet.new([45..55, 63..63, 78..80, 82..85, 90..99])
421
421
+
422
422
+
map: %Mapping{values: [{0..68, 1..69}, {69..69, 0..0}]}
423
423
+
curr: RangeSet.new([45..55, 63..63, 78..80, 82..85, 90..99])
424
424
+
inter: RangeSet.new([45..55, 63..63])
425
425
+
diff: RangeSet.new([78..80, 82..85, 90..99])
426
426
+
mapped: RangeSet.new([46..56, 64..64])
427
427
+
RangeSet.new([46..56, 64..64, 78..80, 82..85, 90..99])
428
428
+
429
429
+
map: %Mapping{values: [{56..92, 60..96}, {93..96, 56..59}]}
430
430
+
curr: RangeSet.new([46..56, 64..64, 78..80, 82..85, 90..99])
431
431
+
```
432
432
+
433
433
+
```elixir
434
434
+
light2temp[74]
435
435
+
```
436
436
+
437
437
+
<!-- livebook:{"output":true} -->
438
438
+
439
439
+
```
440
440
+
78
441
441
+
```
442
442
+
443
443
+
<!-- livebook:{"offset":13391,"stamp":{"token":"XCP.YBvV3LijXOIMnujrbQ1UcVgKkKIgzTxWiEVKN6_kRQO7Z54rqDRPZT7cgjsENw1cakYqdxjdW8l0ZieLojSPU1k_oMLqBh0-YpWLbT9dUfZRNKIxmeQgwwCEGOzZ2hdsVw","version":2}} -->