Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Advent of Code 2024 Day 14 Part 1

2024_day14_part1.livemd

Advent of Code 2024 Day 14 Part 1

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
robots = parse_robots.(sample_input)
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
tiles = {11, 7}
0..5
|> Enum.map(fn step ->
  move.(%{p: {2, 4}, v: {2, -3}}, tiles, step)
end)
get_quadrants = fn points, {tx, ty} ->
  init_quadrants = %{
    {0, 0} => 0,
    {0, 1} => 0,
    {1, 0} => 0,
    {1, 1} => 0
  }

  bx = div(tx, 2)
  by = div(ty, 2)

  points
  |> Enum.reduce(init_quadrants, fn {px, py}, acc_quadrants ->
    {
      cond do
        px == bx -> nil
        px < bx -> 0
        true -> 1
      end,
      cond do
        py == by -> nil
        py < by -> 0
        true -> 1
      end
    }
    |> case do
      {nil, _} ->
        acc_quadrants

      {_, nil} ->
        acc_quadrants

      key ->
        Map.put(acc_quadrants, key, Map.get(acc_quadrants, key) + 1)
    end
  end)
end
quadrants =
  robots
  |> Enum.map(fn robot ->
    move.(robot, tiles, 100)
  end)
  |> get_quadrants.(tiles)
Enum.reduce(quadrants, 1, fn {_, num}, acc -> acc * num end)
tiles = {101, 103}
puzzle_input
|> parse_robots.()
|> Enum.map(fn robot ->
  move.(robot, tiles, 100)
end)
|> get_quadrants.(tiles)
|> Enum.reduce(1, fn {_, num}, acc -> acc * num end)