Powered by AppSignal & Oban Pro

d02

d02/d02.livemd

d02

Section

sample = "7 6 4 2 1
1 2 7 8 9
9 7 6 2 1
1 3 2 4 5
8 6 4 4 1
1 3 6 7 9
"
defmodule D02 do
  def parse(input) do
    input
    |> String.split("\n", trim: true)
    |> Enum.map(fn line -> String.split(line) |> Enum.map(&String.to_integer/1) end)
  end

  def is_safe_ord([], _, _), do: true
  def is_safe_ord([_], _, _), do: true

  def is_safe_ord([x0, x1 | xs], skip, ord) do
    ok_pair = (x0 - x1) * ord > 0 && abs(x0 - x1) <= 3

    case {ok_pair, skip > 0} do
      {true, _} -> D02.is_safe_ord([x1 | xs], skip, ord)
      {false, true} -> D02.is_safe_ord([x0 | xs], skip - 1, ord)
      {false, false} -> false
    end
  end

  def is_safe(xs, skip) do
    Enum.any?([-1, 1], &D02.is_safe_ord(xs, skip, &1))
  end

  def part1(parsed) do
    parsed |> Enum.count(&D02.is_safe(&1, 0))
  end

  def part2(parsed) do
    parsed |> Enum.count(&(D02.is_safe(&1, 1) || D02.is_safe(tl(&1), 0)))
  end
end
parsed_sample = D02.parse(sample)
2 = D02.part1(parsed_sample)
4 = D02.part2(parsed_sample)
{:ok, input} = File.read(__DIR__ <> "/input")
parsed = D02.parse(input)
D02.part1(parsed)
# > 426
D02.part2(parsed)