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

Day 7: Bridge Repair

2024/day07.livemd

Day 7: Bridge Repair

Mix.install([:kino])

Section

input = Kino.Input.textarea("Input", monospace: true)
calibrations =
  input
  |> Kino.Input.read()
  |> String.split("\n")
  |> Enum.map(fn equation ->
    equation
    |> String.split(":")
    |> then(fn [target, operants] ->
      {
        String.to_integer(target),
        operants
        |> String.split(" ", trim: true)
        |> Enum.map(&String.to_integer/1)
        |> Enum.reverse()
      }
    end)
  end)
defmodule OperatorFix do
  def solve([operant], target) do
    operant == target
  end

  def solve([operant | ops], target) do
    (rem(target, operant) == 0 && solve(ops, div(target, operant))) ||
      (operant < target &amp;&amp; solve(ops, target - operant))
  end

  def solve2([op], target), do: target == op

  def solve2([operant | ops], target) do
    (rem(target, operant) == 0 &amp;&amp; solve2(ops, div(target, operant))) ||
      (operant < target &amp;&amp; solve2(ops, target - operant)) ||
      (String.ends_with?(to_string(target), to_string(operant)) &amp;&amp;
         solve2(ops, div(target, Integer.pow(10, length(Integer.digits(operant))))))
  end
end
Enum.reduce(calibrations, 0, fn {target, ops}, acc ->
  if OperatorFix.solve(ops, target), do: acc + target, else: acc
end)
Enum.reduce(calibrations, 0, fn {target, ops}, acc ->
  if OperatorFix.solve2(ops, target), do: acc + target, else: acc
end)