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

Advent of Code 2024 Day 13 Part 2

2024_day13_part2.livemd

Advent of Code 2024 Day 13 Part 2

Mix.install([
  {:kino_aoc, "~> 0.1"},
  {:nx, "~> 0.9"}
])

Get Inputs

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2024", "13", System.fetch_env!("LB_SESSION"))

My answer

sample_input =
  """
  Button A: X+94, Y+34
  Button B: X+22, Y+67
  Prize: X=8400, Y=5400
  
  Button A: X+26, Y+66
  Button B: X+67, Y+21
  Prize: X=12748, Y=12176
  
  Button A: X+17, Y+86
  Button B: X+84, Y+37
  Prize: X=7870, Y=6450
  
  Button A: X+69, Y+23
  Button B: X+27, Y+71
  Prize: X=18641, Y=10279
  """
  |> String.trim()
parse_machines = fn input ->
  input
  |> String.split("\n\n")
  |> Enum.map(fn machine_rows ->
    Regex.named_captures(
      ~r/\+(?\d+).*\+(?\d+)\n.*\+(?\d+).*\+(?\d+)\n.*=(?\d+).*=(?\d+)/,
      machine_rows
    )
  end)
  |> Enum.map(fn %{"ax" => ax, "ay" => ay, "bx" => bx, "by" => by, "px" => px, "py" => py} ->
    %{
      A: Nx.tensor([
          [String.to_integer(ax), String.to_integer(bx)],
          [String.to_integer(ay), String.to_integer(by)]
      ], type: :f64),
      b: Nx.tensor([
        String.to_integer(px) + 10000000000000,
        String.to_integer(py) + 10000000000000
      ], type: :f64)
    }
  end)
end
machines = parse_machines.(sample_input)
Nx.LinAlg.solve(
  Nx.tensor([[26, 67], [66, 21]], type: :f64),
  Nx.tensor([10000000012748, 10000000012176], type: :f64)
)
Nx.LinAlg.solve(
  Nx.tensor([[94, 22], [34, 67]], type: :f64),
  Nx.tensor([10000000008400, 10000000005400], type: :f64)
)
get_prize = fn %{A: a, b: b} ->
  x = Nx.LinAlg.solve(a, b)

  if x |> Nx.to_list() |> Enum.all?(&(round(&1 * 100) == round(&1) * 100)) do
    x |> Nx.to_list() |> Enum.map(&round(&1))
  else
    [0, 0]
  end
end
Enum.map(machines, &get_prize.(&1))
get_cost = fn machines ->
  machines
  |> Enum.map(fn machine ->
    machine
    |> get_prize.()
    |> then(fn [num_a, num_b] ->
      num_a * 3 + num_b
    end)
  end)
  |> Enum.sum()
end
get_cost.(machines)
puzzle_input
|> parse_machines.()
|> get_cost.()