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
chore: cleanup 09.2022
hauleth.dev
3 years ago
270ba4fc
6edffc46
+36
-100
1 changed file
expand all
collapse all
unified
split
2022
day09.livemd
+36
-100
2022/day09.livemd
···
39
39
40
40
{dir, String.to_integer(steps)}
41
41
end)
42
42
+
|> Enum.flat_map(fn {dir, steps} -> List.duplicate(dir, steps) end)
42
43
```
43
44
44
45
<!-- livebook:{"output":true} -->
45
46
46
47
```
47
47
-
[
48
48
-
{"L", 1},
49
49
-
{"R", 1},
50
50
-
{"L", 1},
51
51
-
{"U", 1},
52
52
-
{"R", 2},
53
53
-
{"U", 1},
54
54
-
{"D", 2},
55
55
-
{"R", 2},
56
56
-
{"U", 1},
57
57
-
{"D", 2},
58
58
-
{"U", 2},
59
59
-
{"L", 2},
60
60
-
{"D", 1},
61
61
-
{"U", 1},
62
62
-
{"D", 2},
63
63
-
{"L", 2},
64
64
-
{"D", 1},
65
65
-
{"L", 2},
66
66
-
{"D", 2},
67
67
-
{"L", 1},
68
68
-
{"U", 2},
69
69
-
{"R", 2},
70
70
-
{"L", 1},
71
71
-
{"D", 2},
72
72
-
{"L", 2},
73
73
-
{"R", 2},
74
74
-
{"D", 2},
75
75
-
{"L", 1},
76
76
-
{"U", 1},
77
77
-
{"R", 1},
78
78
-
{"U", 1},
79
79
-
{"L", 1},
80
80
-
{"D", 1},
81
81
-
{"R", 1},
82
82
-
{"U", 2},
83
83
-
{"D", 2},
84
84
-
{"R", 1},
85
85
-
{"U", 1},
86
86
-
{"R", 1},
87
87
-
{"L", 1},
88
88
-
{"U", 1},
89
89
-
{"R", 1},
90
90
-
{"D", 1},
91
91
-
{"L", 1},
92
92
-
{"U", 1},
93
93
-
{"R", 1},
94
94
-
{"D", 1},
95
95
-
{"U", 1},
96
96
-
{"D", ...},
97
97
-
{...},
98
98
-
...
99
99
-
]
48
48
+
["L", "R", "L", "U", "R", "R", "U", "D", "D", "R", "R", "U", "D", "D", "U", "U", "L", "L", "D", "U",
49
49
+
"D", "D", "L", "L", "D", "L", "L", "D", "D", "L", "U", "U", "R", "R", "L", "D", "D", "L", "L", "R",
50
50
+
"R", "D", "D", "L", "U", "R", "U", "L", "D", "R", ...]
100
51
```
101
52
102
53
```elixir
103
54
defmodule Rope do
55
55
+
@enforce_keys [:segments]
56
56
+
defstruct [:segments]
57
57
+
104
58
@start %{x: 0, y: 0}
105
59
106
106
-
defstruct segments: [%{x: 0, y: 0}, %{x: 0, y: 0}]
107
107
-
108
60
def new(length),
109
61
do: %__MODULE__{segments: List.duplicate(@start, length + 1)}
110
62
63
63
+
def run(rope, moves) do
64
64
+
{_rope, tail_positions} =
65
65
+
Enum.reduce(moves, {rope, MapSet.new([Rope.last(rope)])}, fn dir, {rope, acc} ->
66
66
+
new_rope = Rope.move(rope, dir)
67
67
+
68
68
+
{new_rope, MapSet.put(acc, Rope.last(new_rope))}
69
69
+
end)
70
70
+
71
71
+
MapSet.size(tail_positions)
72
72
+
end
73
73
+
111
74
def last(%__MODULE__{segments: list}), do: List.last(list)
112
75
113
76
def move(%__MODULE__{segments: [%{x: x, y: y} | tails]}, dir) do
114
77
head =
115
78
case dir do
116
116
-
"U" -> %{x: x + 1, y: y}
117
117
-
"D" -> %{x: x - 1, y: y}
118
118
-
"L" -> %{x: x, y: y + 1}
119
119
-
"R" -> %{x: x, y: y - 1}
79
79
+
"L" -> %{x: x + 1, y: y}
80
80
+
"R" -> %{x: x - 1, y: y}
81
81
+
"U" -> %{x: x, y: y + 1}
82
82
+
"D" -> %{x: x, y: y - 1}
120
83
end
121
84
122
122
-
segments = move_tails([head | tails])
123
123
-
124
124
-
%__MODULE__{segments: segments}
85
85
+
%__MODULE__{segments: move_tails([head | tails])}
125
86
end
126
87
127
88
defp move_tails([]), do: []
···
132
93
when abs(head.x - tail.x) < 2 and abs(head.y - tail.y) < 2,
133
94
do: rope
134
95
135
135
-
defp move_tails([head, tail | rest])
136
136
-
when abs(head.y - tail.y) < 2,
137
137
-
do: [head | move_tails([%{x: head.x - sgn(head.x - tail.x), y: head.y} | rest])]
138
138
-
139
139
-
defp move_tails([head, tail | rest])
140
140
-
when abs(head.x - tail.x) < 2,
141
141
-
do: [head | move_tails([%{x: head.x, y: head.y - sgn(head.y - tail.y)} | rest])]
142
142
-
143
143
-
defp move_tails([head, tail | rest]),
144
144
-
do: [
145
145
-
head
146
146
-
| move_tails([%{x: head.x - sgn(head.x - tail.x), y: head.y - sgn(head.y - tail.y)} | rest])
147
147
-
]
96
96
+
defp move_tails([head, tail | rest]) do
97
97
+
{dx, dy} = step(head, tail)
98
98
+
[head | move_tails([%{x: head.x - dx, y: head.y - dy} | rest])]
99
99
+
end
148
100
149
101
def sgn(0), do: 0
150
102
def sgn(n) when n < 0, do: -1
151
103
def sgn(_), do: 1
104
104
+
105
105
+
defp step(%{x: x1, y: y1}, %{x: x2, y: y2}) do
106
106
+
{sgn(div(x1 - x2, 2)), sgn(div(y1 - y2, 2))}
107
107
+
end
152
108
end
153
109
```
154
110
155
111
<!-- livebook:{"output":true} -->
156
112
157
113
```
158
158
-
{:module, Rope, <<70, 79, 82, 49, 0, 0, 21, ...>>, {:sgn, 1}}
114
114
+
{:module, Rope, <<70, 79, 82, 49, 0, 0, 23, ...>>, {:step, 2}}
159
115
```
160
116
161
161
-
```elixir
162
162
-
rope = Rope.new(1)
163
163
-
164
164
-
{_rope, tail_positions} =
165
165
-
moves
166
166
-
|> Enum.flat_map(fn {dir, steps} -> List.duplicate(dir, steps) end)
167
167
-
|> Enum.reduce({rope, MapSet.new([Rope.last(rope)])}, fn dir, {rope, acc} ->
168
168
-
new_rope = Rope.move(rope, dir)
169
169
-
170
170
-
{new_rope, MapSet.put(acc, Rope.last(new_rope))}
171
171
-
end)
117
117
+
## Task 1
172
118
173
173
-
MapSet.size(tail_positions)
119
119
+
```elixir
120
120
+
Rope.run(Rope.new(1), moves)
174
121
```
175
122
176
123
<!-- livebook:{"output":true} -->
···
182
129
## Task 2
183
130
184
131
```elixir
185
185
-
rope = Rope.new(9)
186
186
-
187
187
-
{_rope, tail_positions} =
188
188
-
moves
189
189
-
|> Enum.flat_map(fn {dir, steps} -> List.duplicate(dir, steps) end)
190
190
-
|> Enum.reduce({rope, MapSet.new([Rope.last(rope)])}, fn dir, {rope, acc} ->
191
191
-
new_rope = Rope.move(rope, dir)
192
192
-
193
193
-
{new_rope, MapSet.put(acc, Rope.last(new_rope))}
194
194
-
end)
195
195
-
196
196
-
MapSet.size(tail_positions)
132
132
+
Rope.run(Rope.new(9), moves)
197
133
```
198
134
199
135
<!-- livebook:{"output":true} -->