— Day 2: Red-Nosed Reports —
Mix.install([{:kino_aoc, "~> 0.1"}])
Section
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2024", "2", System.fetch_env!("LB_AOC_SESSION_COOKIE"))
defmodule RedNosedReports do
def parse(input) do
input
|> String.split("\n")
|> Enum.map(fn report ->
for level <- String.split(report) do
String.to_integer(level)
end
end)
end
def ordered?(report) do
asc? = report == Enum.sort(report)
desc? = report == Enum.sort(report, :desc)
asc? || desc?
end
def gradual?([first | rest]) do
result =
Enum.reduce_while(rest, first, fn
next_level, prev_level ->
if abs(prev_level - next_level) in 1..3 do
{:cont, next_level}
else
{:halt, :unsafe}
end
end)
result != :unsafe
end
def safe?(report), do: ordered?(report) && gradual?(report)
def dampener(report) do
if safe?(report) do
true
else
Enum.reduce_while(report, false, fn level, _acc ->
if safe?(report -- [level]) || safe?(Enum.reverse(report) -- [level]) do
{:halt, true}
else
{:cont, false}
end
end)
end
end
end
import RedNosedReports
puzzle_input
|> parse()
|> Enum.map(&safe?/1)
|> Enum.count(& &1)
import RedNosedReports
puzzle_input
|> parse()
|> Enum.map(&dampener/1)
|> Enum.count(& &1)