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

Advent of code 2024 - day 2

aoc2024day2.livemd

Advent of code 2024 - day 2

Mix.install([
  {:kino, "~> 0.14.2"}
])

Part 1

https://adventofcode.com/2024/day/2

textarea = Kino.Input.textarea("Enter the input:")
input = Kino.Input.read(textarea)

reports =
  input
  |> String.split("\n", trim: true)
  |> Enum.map(fn report -> String.split(report) |> Enum.map(&String.to_integer/1) end)

length(reports)
defmodule TestReport do
  def is_safe?(report) do
    deltas =
      Enum.chunk_every(report, 2, 1, :discard)
      |> Enum.map(fn from_to -> Enum.at(from_to, 1) - Enum.at(from_to, 0) end)

    minimum = Enum.min(deltas)
    maximum = Enum.max(deltas)
    abs_minimum = min(abs(minimum), abs(maximum))
    abs_maximum = max(abs(minimum), abs(maximum))
    same_sign = (minimum >= 0 and maximum >= 0) or (minimum < 0 and maximum < 0)

    abs(abs_minimum) >= 1 and abs(abs_maximum) <= 3 and same_sign
  end
end
Enum.map(reports, &amp;TestReport.is_safe?/1)
|> Enum.filter(&amp; &amp;1)
|> Enum.count()

Part 2

Enum.map(reports, fn report ->
  is_safe = TestReport.is_safe?(report)

  Enum.reduce_while(1..length(report), is_safe, fn pos, acc ->
    if acc do
      {:halt, acc}
    else
      corrected_report = List.delete_at(report, pos - 1)
      {:cont, TestReport.is_safe?(corrected_report)}
    end
  end)
end)
|> Enum.filter(&amp; &amp;1)
|> Enum.count()