Day 09
Mix.install([
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
])
:ok
Setup
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2022", "9", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
{:ok,
"L 1\nR 1\nL 1\nU 1\nR 2\nU 1\nD 2\nR 2\nU 1\nD 2\nU 2\nL 2\nD 1\nU 1\nD 2\nL 2\nD 1\nL 2\nD 2\nL 1\nU 2\nR 2\nL 1\nD 2\nL 2\nR 2\nD 2\nL 1\nU 1\nR 1\nU 1\nL 1\nD 1\nR 1\nU 2\nD 2\nR 1\nU 1\nR 1\nL 1\nU 1\nR 1\nD 1\nL 1\nU 1\nR 1\nD 1\nU 1\nD 1\nU 1\nR 2\nL 2\nD 2\nL 2\nR 1\nU 2\nL 2\nR 1\nU 1\nR 2\nD 2\nR 2\nL 2\nU 2\nR 2\nD 2\nR 1\nU 1\nL 2\nR 1\nU 1\nD 2\nU 2\nD 1\nR 2\nL 2\nD 2\nL 2\nR 2\nU 1\nR 2\nL 2\nD 2\nL 1\nD 1\nR 2\nL 1\nU 2\nR 1\nU 2\nD 1\nU 2\nD 1\nL 1\nR 2\nD 2\nR 2\nU 2\nR 1\nU 2\nR 2\nU 1\nR 1\nD 2\nU 2\nR 2\nU 1\nR 2\nD 2\nR 1\nL 1\nU 3\nL 2\nU 1\nL 2\nU 1\nD 1\nU 2\nD 1\nU 2\nR 2\nL 1\nU 3\nR 1\nU 1\nR 3\nL 3\nD 3\nL 2\nU 1\nD 3\nU 1\nR 1\nL 1\nR 2\nL 1\nR 3\nL 3\nD 1\nR 2\nL 3\nU 3\nD 1\nL 2\nU 2\nD 2\nL 2\nU 1\nR 1\nL 2\nR 3\nL 3\nD 3\nR 2\nD 3\nU 1\nL 3\nR 1\nU 2\nL 1\nD 3\nL 1\nU 1\nD 3\nL 3\nU 2\nD 1\nU 2\nL 3\nR 1\nU 2\nD 2\nR 3\nD 3\nU 2\nD 3\nL 3\nR 3\nL 1\nU 3\nL 1\nD 1\nL 2\nD 2\nR 1\nL 3\nR 2\nL 3\nR 3\nL 1\nD 1\nU 3\nL 2\nR 2\nL 2\nD 3\nU 3\nL 3\nU 3\nD 1\nU 2\nR 2\nU 1\nD 3\nL 3\nR 1\nL 3\nU 3\nD 1\nL 3\nD 2\nR 1\nU 1\nR 1\nD 2\nL 2\nU 1\nL 2\nR 2\nL 2\nD 3\nU 3\nD 4\nL 3\nD 4\nR 3\nL 2\nU 3\nR 3\nU 1\nR 4\nU 2\nD 1\nR 3\nL 1\nR 1\nD 3\nR 2\nD 1\nR 2\nL 2\nU 2\nD 1\nR 1\nU 2\nR 3\nL 2\nD 1\nU 3\nR 2\nD 4\nL 3\nU 1\nR 1\nD 2\nU 1\nR 3\nL 4\nD 2\nL 1\nU 3\nL 2\nU 3\nR 1\nD 1\nL 2\nR 4\nD 4\nU 1\nR 3\nU 3\nR 1\nU 3\nL 2\nU 3\nL 2\nD 4\nU 1\nR 1\nL 2\nR 2\nD 2\nL 2\nD 2\nU 4\nD 4\nL 2\nU 2\nD 3\nL 4\nU 4\nD 4\nR 1\nD 4\nR 1\nD 1\nL 1\nR 1\nL 1\nD 2\nL 4\nD 2\nR 3\nL 1\nD 2\nU 3\nL 2\nU 3\nR 4\nD 4\nU 1\nL 1\nU 4\nL 4\nU 3\nD 2\nR 3\nL 1\nD 3\nU 3\nR 1\nL 3\nU 1\nD 1\nR 1\nU 3\nR 2\nL 1\nD 1\nL 3\nU 1\nD 1\nL 2\nR 3\nU 4\nL 5\nD 5\nR 5\nD 3\nU 3\nD 1\nL 5\nR 2\nU 1\nL 2\nD 1\nL 1\nD 4\nR 1\nU 1\nL 1\nU 1\nD 3\nL 4\nD 1\nU 5\nL 1\nR 5\nL 2\nR 4\nD 5\nU 2\nD 3\nU 4\nL 1\nR 2\nU 4\nL 4\nD 3\nR 1\nU 1\nR 3\nD 3\nU 5\nL 3\nD 3\nU 5\nR 4\nL 1\nD 4\nU 1\nL 1\nR 4\nD 5\nL 5\nD 3\nR 5\nU 3\nR 2\nD 2\nU 2\nD 5\nR 5\nD 5\nR 2\nD 5\nU 2\nD 2\nR 1\nL 5\nD 2\nU 2\nR 5\nU 1\nD 5\nU 5\nL 2\nD 5\nL 1\nR 4\nU 4\nD 1\nL 5\nU 4\nL 1\nR 3\nL 3\nR 3\nL 3\nD 3\nR 4\nU 5\nL 2\nD 3\nU 2\nL 1\nR 5\nU 1\nL 3\nU 4\nL 4\nD 4\nR 1\nD 4\nR 5\nD 5\nU 5\nR 5\nL 3\nD 3\nU 2\nR 5\nU 5\nR 2\nD 5\nR 1\nU 2\nD 5\nL 3\nR 5\nU 5\nR 4\nD 6\nL 4\nU 4\nL 6\nR 2\nL 4\nU 5\nL 1\nU 6\nD 4\nR 3\nU 2\nR 1\nD 5\nL 4\nU 2\nR 6\nU 1\nL 2\nD 6\nU 1\nR 2\nL 3\nR 2\nL 5\nU 1\nR 3\nD 3\nL 4\nR 5\nU 1\nD 3\nR 6\nD 5\nR 4\nD 3\nU 2\nD 4\nR 5\nU 4\nR 2\nL 2\nU 5\nD 5\nU 6\nD 4\nU 5\nL 5\nR 1\nD 3\nR 3\nL 3\nD 3\nL 3\nU 6\nR 5\nD 6\nU 5\nL 1\nR 4\nL 1\nU 4\nL 5\nD 5\nU 4\nD 3\nR 3\nL 4\nR 4\nU 6\nL 5\nD 2\nU 3\nR 4\nU 5\nL 5\nD 6\nR 5\nD 5\nL 3\nU 6\nL 3\nU 5\nD 2\nU 4\nR 4\nU 3\nD 1\nR 2\nL 6\nR 2\nL 3\nU 5\nL 1\nR 4\nD 2\nU 5\nD 2\nR 4\nU 6\nR 6\nL 6\nU 6\nL 4\nR 5\nD 3\nU 1\nD 6\nL 1\nD 3\nL 4\nD 6\nU 3\nD 2\nL 2\nU 5\nD 2\nU 5\nD 6\nR 4\nD 1\nU 1\nD 5\nU 1\nL 7\nU 3\nR 3\nU 5\nD 2\nR 7\nD 6\nL 7\nR 6\nL 3\nR 3\nU 1\nL 4\nD 4\nL 6\nR 1\nU 4\nL 3\nR 3\nD 3\nL 2\nD 7\nU 7\nD 7\nR 2\nL 6\nD 2\nR 6\nD 6\nU 5\nL 4\nU 3\nD 6\nU 3\nD 1\nL 7\nU 7\nL 4\nR 3\nD 6\nU 2\nL 6\nD 3\nU 7\nD 2\nR 7\nD 4\nL 4\nR 4\nU 2\nD 3\nU 2\nL 4\nR 4\nL 4\nD 6\nR 4\nU 1\nR 7\nD 7\nU 7\nR 6\nD 4\nU 2\nD 4\nL 5\nU 4\nD 6\nR 4\nU 2\nR 1\nU 4\nD 5\nR 1\nD 7\nR 4\nU 1\nD 4\nU 6\nL 6\nR 1\nD 1\nR 1\nD 6\nR 6\nD 3\nU 1\nD 5\nR 4\nL 1\nD 6\nR 6\nL 8\nU 1\nD 7\nR 4\nL 2\nR 6\nU 7\nL 2\nD 5\nR 6\nD 3\nL 4\nR 5\nU 7\nL 3\nU 8\nL 1\nU 6\nL 8\nR 7\nD 2\nU 3\nR 4\nL 8\nD 4\nL 1\nU 1\nD 7\nU 8\nR 7\nD 2\nL 5\nU 6\nD 7\nR 4\nL 1\nR 3\nU 1\nR 2\nU 1\nD 7\nR 6\nU 7\nD 6\nL 2\nD 8\nU 4\nR 8\nL 5\nD 6\nL 7\nU 7\nR 8\nL 5\nD 5\nR 4\nL 5\nU 8\nD 4\nU 6\nD 2\nU 5\nR 7\nL 8\nU 7\nR 3\nL 8\nR 6\nD 4\nR 2\nD 6\nR 5\nD 2\nU 6\nL 4\nU 8\nR 3\nU 1\nL 6\nR 1\nL 3\nR 1\nU 3\nL 8\nD 5\nU 6\nL 8\nD 6\nR 2\nU 6\nR 4\nL 8\nD 1\nR 6\nD 8\nU 6\nD 6\nL 3\nU 4\nD 2\nL 2\nD 7\nL 5\nU 3\nR 8\nD 6\nR 5\nL 8\nU 5\nL 9\nR 7\nD 5\nR 2\nU 5\nL 3\nD 9\nR 4\nU 1\nL 3\nR 5\nL 7\nR 8\nD 1\nU 4\nL 4\nR 3\nU 8\nL 8\nD 8\nU 9\nR 6\nU 3\nR 2\nU 8\nD 9\nR 3\nL 2\nU 9\nR 9\nL 8\nD 2\nR 1\nL 8\nU 7\nR 3\nL 1\nR 9\nL 4\nR 2\nU 3\nD 8\nR 5\nU 9\nL 9\nR 1\nD 5\nR 5\nU 4\nL 9\nR 6\nD 5\nL 2\nR 6\nU 1\nD 5\nL 3\nR 1\nU 5\nR 4\nD 4\nU 8\nD 2\nU 6\nR 6\nU 5\nR 3\nU 5\nR 5\nL 8\nD 9\nL 7\nR 1\nU 7\nR 5\nU 6\nR 8\nU 2\nR 2\nU 8\nR 7\nD 3\nR 6\nL 8\nR 4\nL 8\nR 8\nU 8\nR 3\nL 3\nU 1\nL 9\nD 9\nR 9\nU 4\nR 1\nL 3\nD 4\nU 5\nR 7\nD 6\nL 9\nU 7\nL 4\nR 8\nU 8\nD 4\nL 5\nD 9\nU 2\nD 9\nR 4\nD 8\nR 8\nD 8\nU 9\nL 6\nR 6\nL 2\nU 9\nL 4\nU 10\nL 1\nR 10\nD 3\nU 6\nR 5\nD 3\nR 4\nL 4\nU 7\nD 9\nR 2\nD 10\nU 9\nL 7\nD 4\nR 2\nL 10\nD 5\nR 5\nU 9\nR 4\nL 7\nR 5\nD 3\nR 6\nD 8\nR 6\nD 10\nR 7\nU 4\nD 5\nU 6\nL 3\nD 3\nU 10\nR 10\nU 10\nD 9\nR 6\nD 2\nR 9\nD 8\nR 7\nU 10\nR 4\nU 6\nR 7\nU 2\nR 5\nU 6\nL 4\nU 8\nL 6\nD 8\nR 2\nU 2\nL 4\nU 4\nR 5\nU 10\nD 8\nU 7\nR 5\nD 3\nL 2\nR 9\nU 10\nL 1\nU 5\nL 1\nD 3\nL 9\nR 9\nU 2\nD 3\nU 8\nR 10\nL 2\nU 9\nD 4\nU 4\nD 10\nL 4\nD 3\nR 3\nL 2\nU 8\nL 4\nD 6\nR 2\nL 3\nD 6\nL 4\nD 5\nL 7\nU 9\nL 3\nD 4\nR 6\nL 10\nU 5\nL 3\nR 3\nD 6\nU 1\nL 3\nR 5\nD 8\nR 11\nU 2\nL 11\nR 7\nU 8\nR 4\nD 4\nU 6\nD 4\nU 9\nD 5\nR 9\nD 9\n" <> ...}
moves =
puzzle_input
|> String.split("\n", trim: true)
|> Enum.flat_map(fn line ->
[dir, steps] = String.split(line)
deltas =
case dir do
"R" -> {-1, 0}
"L" -> {+1, 0}
"U" -> {0, +1}
"D" -> {0, -1}
end
List.duplicate(deltas, String.to_integer(steps))
end)
[
{1, 0},
{-1, 0},
{1, 0},
{0, 1},
{-1, 0},
{-1, 0},
{0, 1},
{0, -1},
{0, -1},
{-1, 0},
{-1, 0},
{0, 1},
{0, -1},
{0, -1},
{0, 1},
{0, 1},
{1, 0},
{1, 0},
{0, -1},
{0, 1},
{0, -1},
{0, -1},
{1, 0},
{1, 0},
{0, -1},
{1, 0},
{1, 0},
{0, -1},
{0, -1},
{1, 0},
{0, 1},
{0, 1},
{-1, 0},
{-1, 0},
{1, 0},
{0, -1},
{0, -1},
{1, 0},
{1, 0},
{-1, 0},
{-1, 0},
{0, -1},
{0, -1},
{1, 0},
{0, 1},
{-1, 0},
{0, 1},
{1, 0},
{0, ...},
{...},
...
]
defmodule Rope do
@enforce_keys [:segments]
defstruct [:segments]
@start %{x: 0, y: 0}
def new(length),
do: %__MODULE__{segments: List.duplicate(@start, length + 1)}
def run(rope, moves) do
{_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))}
end)
MapSet.size(tail_positions)
end
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])}
end
defp move_tails([]), do: []
defp move_tails([head]), do: [head]
# When nothing else moves, then stop
defp move_tails([head, tail | _] = rope)
when abs(head.x - tail.x) < 2 and abs(head.y - tail.y) < 2,
do: rope
defp move_tails([head, tail | rest]) do
{dx, dy} = step(head, tail)
[head | move_tails([%{x: tail.x + dx, y: tail.y + dy} | rest])]
end
def sgn(0), do: 0
def sgn(n) when n < 0, do: -1
def sgn(_), do: 1
defp step(%{x: x1, y: y1}, %{x: x2, y: y2}),
do: {sgn(x1 - x2), sgn(y1 - y2)}
end
{:module, Rope, <<70, 79, 82, 49, 0, 0, 22, ...>>, {:step, 2}}
Task 1
Rope.run(Rope.new(1), moves)
5960
Task 2
Rope.run(Rope.new(9), moves)
2327