Advent of Code - Day 9
Mix.install(
[
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
],
force: true
)
Section
{:ok, puzzle_input} = KinoAOC.download_puzzle("2022", "9", System.fetch_env!("LB_SESSION"))
input = """
R 4
U 4
L 3
D 1
R 4
D 1
L 5
R 2
"""
defmodule Rope do
def move_head(input) do
input
|> String.split("\n", trim: true)
|> Stream.map(fn l -> String.split(l, " ") end)
|> Stream.map(fn [move, count] -> {move, String.to_integer(count)} end)
|> Stream.flat_map(fn {dir, count} -> Stream.map(0..(count - 1), fn _ -> dir end) end)
|> Stream.scan({0, 0}, &make_head_move/2)
end
def move_tail(head_positions) do
Stream.scan(head_positions, {0, 0}, &make_tail_move/2)
end
defp make_head_move("R", {x, y}), do: {x + 1, y}
defp make_head_move("L", {x, y}), do: {x - 1, y}
defp make_head_move("U", {x, y}), do: {x, y + 1}
defp make_head_move("D", {x, y}), do: {x, y - 1}
defp make_tail_move({hx, hy}, {tx, ty}) when abs(hx - tx) > 1 or abs(hy - ty) > 1,
do: {tx + get_cross_direction(hx, tx), ty + get_cross_direction(hy, ty)}
defp make_tail_move(_head, tail), do: tail
defp get_cross_direction(x, x), do: 0
defp get_cross_direction(head, tail) when head > tail, do: 1
defp get_cross_direction(_head, _tail), do: -1
end
Part 1
puzzle_input
|> Rope.move_head()
|> Rope.move_tail()
|> Enum.uniq()
|> Enum.count()
Part 2
puzzle_input
|> Rope.move_head()
|> Rope.move_tail()
|> Rope.move_tail()
|> Rope.move_tail()
|> Rope.move_tail()
|> Rope.move_tail()
|> Rope.move_tail()
|> Rope.move_tail()
|> Rope.move_tail()
|> Rope.move_tail()
|> Enum.uniq()
|> Enum.count()