Powered by AppSignal & Oban Pro

Advent of Code 2023 Day 6 - Newton's Approx

2023/day-06-newton.livemd

Advent of Code 2023 Day 6 - Newton’s Approx

Mix.install([
  {:kino_aoc, "~> 0.1.5"}
])

Prep

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2023", "6", System.fetch_env!("LB_AOC_SESSION"))
IO.puts(puzzle_input)
approx = fn t, s, v ->
  v
  |> Stream.unfold(fn v ->
    y = (v - t) * v + s
    k = 2 * v - t
    dv = div(y, k)
    {v, v - dv}
  end)
  |> Stream.chunk_every(2, 1)
  |> Enum.find(&match?([a, a], &1))
  |> hd()
end

Part 1

puzzle_input
|> String.split("\n")
|> Stream.map(&String.split/1)
|> Stream.map(&tl/1)
|> Stream.map(&Enum.map(&1, fn s -> String.to_integer(s) end))
|> Enum.zip()
|> Enum.map(fn {t, s} ->
  approx.(t, s, t) - approx.(t, s, 0) - 1
end)
|> Enum.product()

Part 2

[t, s] =
  puzzle_input
  |> String.split("\n")
  |> Enum.map(fn line ->
    ~r/\d/
    |> Regex.scan(line)
    |> List.flatten()
    |> Enum.join()
    |> String.to_integer()
  end)
approx.(t, s, t) - approx.(t, s, 0) - 1