Advent of Code 2024 Day 14 Part 2
Mix.install([
{:kino_aoc, "~> 0.1"}
])
Get Inputs
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2024", "14", System.fetch_env!("LB_SESSION"))
My answer
sample_input =
"""
p=0,4 v=3,-3
p=6,3 v=-1,-3
p=10,3 v=-1,2
p=2,0 v=2,-1
p=0,0 v=1,3
p=3,0 v=-2,-2
p=7,6 v=-1,-3
p=3,0 v=-1,-2
p=9,3 v=2,3
p=7,3 v=-1,2
p=2,4 v=2,-3
p=9,5 v=-3,-3
"""
|> String.trim()
parse_robots = fn input ->
input
|> String.split("\n")
|> Enum.map(fn row ->
Regex.named_captures(
~r/p=(?\d+),(?\d+) v=(?\-*\d+),(?\-*\d+)/,
row
)
end)
|> Enum.map(fn %{"px" => px, "py" => py, "vx" => vx, "vy" => vy} ->
%{
p: {String.to_integer(px), String.to_integer(py)},
v: {String.to_integer(vx), String.to_integer(vy)}
}
end)
end
move = fn %{p: {px, py}, v: {vx, vy}}, {tx, ty}, step ->
{
(px + vx * step) |> rem(tx) |> Kernel.+(tx) |> rem(tx),
(py + vy * step) |> rem(ty) |> Kernel.+(ty) |> rem(ty)
}
end
display_map = fn points, {tx, ty} ->
0..ty-1
|> Enum.map(fn y ->
0..tx-1
|> Enum.map(fn x ->
case Enum.find(points, fn point -> point == {x, y} end) do
nil -> " "
_ -> "X"
end
end)
|> Enum.join()
end)
|> Enum.join("\n")
end
tiles = {11, 7}
sample_input
|> parse_robots.()
|> Enum.map(fn robot ->
move.(robot, tiles, 100)
end)
|> display_map.(tiles)
|> Kino.Text.new(terminal: true)
robots = parse_robots.(puzzle_input)
tiles = {101, 103}
1..10000
|> Enum.find(fn step ->
points =
robots
|> Enum.map(fn robot ->
move.(robot, tiles, step)
end)
|> Enum.sort()
Enum.uniq(points) == points
end)
|> then(fn step ->
IO.inspect(step)
robots
|> Enum.map(fn robot ->
move.(robot, tiles, step)
end)
|> display_map.(tiles)
|> Kino.Text.new(terminal: true)
end)