Advent of Code 2024
Mix.install([
{:req, "~> 0.5.8"},
{:kino, "~> 0.14.2"}
])
Day 14
Kino.configure(inspect: [charlists: :as_lists])
input =
"https://adventofcode.com/2024/day/14/input"
|> Req.get!(headers: [cookie: "session=#{System.get_env("AOC_COOKIE")}"])
|> Map.get(:body)
sample =
"""
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
"""
defmodule Day14 do
def parse(input) do
input
|> String.split("\n", trim: true)
|> Enum.map(fn line ->
[px, py, vx, vy] =
Regex.run(~r/p=(-?\d+),(-?\d+) v=(-?\d+),(-?\d+)/, line, capture: :all_but_first)
|> Enum.map(&String.to_integer/1)
[{px, py}, {vx, vy}]
end)
end
def step(robots, n, {w, h}) do
robots
|> Enum.map(fn [{px, py}, {vx, vy}] ->
px = Integer.mod(px + n * vx, w)
py = Integer.mod(py + n * vy, h)
{px, py}
end)
end
def step2(robots, {w, h}) do
robots
|> Enum.map(fn [{px, py}, {vx, vy}] ->
[{Integer.mod(px + vx, w), Integer.mod(py + vy, h)}, {vx, vy}]
end)
end
def to_string(robots, {w, h}) do
grid = robots |> Enum.map(&Enum.at(&1, 0)) |> MapSet.new()
for(
y <- 0..(h - 1),
x <- 0..(w - 1),
do: if(MapSet.member?(grid, {x, y}), do: "o", else: " ")
)
|> Enum.chunk_every(w)
|> Enum.map(&Enum.join(&1))
|> Enum.join("\n")
end
end
import Day14
Part 1
w = 101
h = 103
mid_x = div(w, 2)
mid_y = div(h, 2)
input
|> parse()
|> step(100, {w, h})
|> Enum.reject(fn {px, py} ->
px == mid_x || py == mid_y
end)
|> Enum.frequencies_by(fn {px, py} ->
case {px, py} do
{px, py} when px < mid_x and py < mid_y -> 1
{px, py} when px > mid_x and py < mid_y -> 2
{px, py} when px < mid_x and py > mid_y -> 3
{px, py} when px > mid_x and py > mid_y -> 4
end
end)
|> Map.values()
|> Enum.product()
Part 2
robots =
input
|> parse()
{i, robots, out} =
Stream.iterate(1, &(&1 + 1))
|> Enum.reduce_while(robots, fn i, robots ->
robots = step2(robots, {w, h})
out = to_string(robots, {w, h})
if String.contains?(out, "oooooooooo") do
{:halt, {i, robots, out}}
else
{:cont, robots}
end
end)
[
"Iteration: #{i}",
"```",
out,
"```"
]
|> Enum.join("\n")
|> Kino.Markdown.new()