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

Advent of Code 2024 Day 14 Part 2

2024_day14_part2.livemd

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)