Powered by AppSignal & Oban Pro

d13

d13/d13.livemd

d13

Section

sample = "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
"

Regex.scan(~r/Button A: X\+(\d+), Y\+(\d+)\nButton B: X\+(\d+), Y\+(\d+)\nPrize: X=(\d+), Y=(\d+)/, sample)
|> Enum.map(fn matches -> Enum.drop(matches, 1) |> Enum.map(&String.to_integer/1) end)
# String.split(String.trim(sample), "\n\n")
# |> Enum.map()
ExUnit.start()

defmodule D13 do
  def parse(input) do
    Regex.scan(
      ~r/Button A: X\+(\d+), Y\+(\d+)\nButton B: X\+(\d+), Y\+(\d+)\nPrize: X=(\d+), Y=(\d+)/,
      input
    )
    |> Enum.map(fn matches -> Enum.drop(matches, 1) |> Enum.map(&String.to_integer/1) end)
  end

  def cost([{at, ax, ay}, {bt, bx, by}], x, y) do
    b = div(y * ax - x * ay, by * ax - bx * ay)
    a = div(x - b * bx, ax)
    if a * ax + b * bx == x and a * ay + b * by == y do
      a * at + b * bt
    else
      nil
    end
  end

  def part1(parsed, offset \\ 0) do
    for [ax, ay, bx, by, x, y] <- parsed, reduce: 0 do
      acc -> case D13.cost([{3, ax, ay}, {1, bx, by}], x + offset, y + offset) do
        nil -> acc
        tokens -> acc + tokens
      end
    end
  end

  def part2(parsed) do
    D13.part1(parsed, 10000000000000)
  end

  use ExUnit.Case

  test "sample" do
    sample = "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
"
    assert 480 == D13.parse(sample) |> D13.part1()
    # assert 1206 == D12.parse(sample) |> D13.part2()
  end
end

ExUnit.run()
input = File.read!(__DIR__ <> "/input")
parsed = D13.parse(input)
D13.part1(parsed)
D13.part2(parsed)