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
Day 04 od 2025
hauleth.dev
3 months ago
26bec5c3
b5ea05b3
verified
This commit was signed with the committer's
known signature
.
hauleth.dev
SSH Key Fingerprint:
SHA256:1hEP8QO8nM2KQfQ8jK4Q19y/CmqVZQI/cNSht3c1QlI=
+78
1 changed file
expand all
collapse all
unified
split
2025
day04.livemd
+78
2025/day04.livemd
···
1
1
+
# Day 04
2
2
+
3
3
+
```elixir
4
4
+
Mix.install([:kino_aoc])
5
5
+
```
6
6
+
7
7
+
## Setup
8
8
+
9
9
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiI0Iiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjUifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
10
10
+
11
11
+
```elixir
12
12
+
{:ok, puzzle_input} =
13
13
+
KinoAOC.download_puzzle("2025", "4", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
14
14
+
```
15
15
+
16
16
+
```elixir
17
17
+
rolls =
18
18
+
puzzle_input
19
19
+
|> String.split("\n", trim: true)
20
20
+
|> Enum.with_index()
21
21
+
|> Enum.flat_map(fn {line, row} ->
22
22
+
line
23
23
+
|> String.to_charlist()
24
24
+
|> Enum.with_index()
25
25
+
|> Enum.filter(&(elem(&1, 0) == ?@))
26
26
+
|> Enum.map(&{elem(&1, 1), row})
27
27
+
end)
28
28
+
|> MapSet.new()
29
29
+
```
30
30
+
31
31
+
## Implementation
32
32
+
33
33
+
```elixir
34
34
+
defmodule PaperRolls do
35
35
+
def adjacent({x, y}) do
36
36
+
for dx <- -1..1,
37
37
+
dy <- -1..1,
38
38
+
{dx, dy} != {0, 0},
39
39
+
do: {x + dx, y + dy}
40
40
+
end
41
41
+
42
42
+
def free?(pos, map) do
43
43
+
pos
44
44
+
|> adjacent()
45
45
+
|> Enum.count(&(&1 in map))
46
46
+
|> then(&(&1 < 4))
47
47
+
end
48
48
+
end
49
49
+
```
50
50
+
51
51
+
## Part 1
52
52
+
53
53
+
```elixir
54
54
+
Enum.count(rolls, &PaperRolls.free?(&1, rolls))
55
55
+
```
56
56
+
57
57
+
## Part 2
58
58
+
59
59
+
```elixir
60
60
+
cleaned =
61
61
+
Stream.repeatedly(fn -> [] end)
62
62
+
|> Enum.reduce_while(rolls, fn _, acc ->
63
63
+
removable =
64
64
+
Enum.filter(acc, &PaperRolls.free?(&1, acc))
65
65
+
|> MapSet.new()
66
66
+
67
67
+
case MapSet.difference(acc, removable) do
68
68
+
^acc -> {:halt, acc}
69
69
+
remaining -> {:cont, remaining}
70
70
+
end
71
71
+
end)
72
72
+
```
73
73
+
74
74
+
```elixir
75
75
+
MapSet.size(rolls) - MapSet.size(cleaned)
76
76
+
```
77
77
+
78
78
+
<!-- livebook:{"offset":1486,"stamp":{"token":"XCP.deDYlsmx1l6_24twLKmjhZpjVr-zKpCk4kKaQFxGe1gppbfdc-7UyFIZxpcR_jVCGfX6vDlmYQ7ACpVB7bxafYi0X3Avsi-upj46ogSc5zRBoDdxStrGLSLdSmW_EsudIg","version":2}} -->