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

Day 2

day2.livemd

Day 2

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

Part 1

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

input = Kino.FS.file_path("input.txt") |> File.read!()

rows = String.trim(input)
  |> String.split("\n") 
  |> Enum.map(fn raw_row -> String.split(raw_row) end)
  |> Enum.map(fn row ->
    Enum.map(row, fn item -> String.to_integer(item) end)
  end)
defmodule Checker do
  def check(row = [first, second | _]) do
    if first >= second, do: do_check(row, :decreasing),
      else: do_check(row, :increasing)
  end
  
  defp do_check([_], _), do: :safe  # One element remaining
 
  defp do_check([first, second | rest], direction)
    when (direction == :decreasing)
      and (first > second and second >= first - 3) do
    do_check([second | rest], direction)
  end
  
  defp do_check([first, second | rest], direction)
    when (direction == :increasing)
      and (first < second and second <= first + 3) do
    do_check([second | rest], direction)
  end
  
  defp do_check(_, _), do: :unsafe  # Default
end

result = Enum.map(rows, fn row -> Checker.check(row) end)
  |> Enum.filter(fn val -> val == :safe end)
  |> Enum.count()

Part 2

permutate = fn row -> Enum.map(
    0..length(row),
    fn index -> List.delete_at(row, index) end
  ) end

result = Enum.map(rows, fn row -> permutate.(row) end)
  |> Enum.map(fn permutations ->
      Enum.map(permutations, fn perm -> Checker.check(perm) end)
     end)
  |> Enum.filter(fn row_results -> :safe in row_results end)
  |> Enum.count()