···
|> String.split("\n", trim: true)
[dir, steps] = String.split(line)
-
{dir, String.to_integer(steps)}
-
|> Enum.flat_map(fn {dir, steps} -> List.duplicate(dir, steps) end)
<!-- livebook:{"output":true} -->
-
["L", "R", "L", "U", "R", "R", "U", "D", "D", "R", "R", "U", "D", "D", "U", "U", "L", "L", "D", "U",
-
"D", "D", "L", "L", "D", "L", "L", "D", "D", "L", "U", "U", "R", "R", "L", "D", "D", "L", "L", "R",
-
"R", "D", "D", "L", "U", "R", "U", "L", "D", "R", ...]
···
{_rope, tail_positions} =
-
Enum.reduce(moves, {rope, MapSet.new([Rope.last(rope)])}, fn dir, {rope, acc} ->
new_rope = Rope.move(rope, dir)
{new_rope, MapSet.put(acc, Rope.last(new_rope))}
···
def last(%__MODULE__{segments: list}), do: List.last(list)
-
def move(%__MODULE__{segments: [%{x: x, y: y} | tails]}, dir) do
-
"L" -> %{x: x + 1, y: y}
-
"R" -> %{x: x - 1, y: y}
-
"U" -> %{x: x, y: y + 1}
-
"D" -> %{x: x, y: y - 1}
%__MODULE__{segments: move_tails([head | tails])}
···
defp move_tails([head, tail | rest]) do
{dx, dy} = step(head, tail)
-
[head | move_tails([%{x: head.x - dx, y: head.y - dy} | rest])]
def sgn(n) when n < 0, do: -1
-
defp step(%{x: x1, y: y1}, %{x: x2, y: y2}) do
-
{sgn(div(x1 - x2, 2)), sgn(div(y1 - y2, 2))}
<!-- livebook:{"output":true} -->
-
{:module, Rope, <<70, 79, 82, 49, 0, 0, 23, ...>>, {:step, 2}}
···
|> String.split("\n", trim: true)
+
|> Enum.flat_map(fn line ->
[dir, steps] = String.split(line)
+
List.duplicate(deltas, String.to_integer(steps))
<!-- livebook:{"output":true} -->
···
{_rope, tail_positions} =
+
Enum.reduce(moves, {rope, MapSet.new()}, fn dir, {rope, acc} ->
new_rope = Rope.move(rope, dir)
{new_rope, MapSet.put(acc, Rope.last(new_rope))}
···
def last(%__MODULE__{segments: list}), do: List.last(list)
+
def move(%__MODULE__{segments: [%{x: x, y: y} | tails]}, {dx, dy}) do
+
head = %{x: x + dx, y: y + dy}
%__MODULE__{segments: move_tails([head | tails])}
···
defp move_tails([head, tail | rest]) do
{dx, dy} = step(head, tail)
+
[head | move_tails([%{x: tail.x + dx, y: tail.y + dy} | rest])]
def sgn(n) when n < 0, do: -1
+
defp step(%{x: x1, y: y1}, %{x: x2, y: y2}),
+
do: {sgn(x1 - x2), sgn(y1 - y2)}
<!-- livebook:{"output":true} -->
+
{:module, Rope, <<70, 79, 82, 49, 0, 0, 22, ...>>, {:step, 2}}