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

2024 Day 2

advent_of_code/2024/day-02.livemd

2024 Day 2

Day 2: Red-Nosed Reports

Day 2: Red-Nosed Reports

Part 1

defmodule AdventOfCode2024Day2Part1 do
  def count_safe_reports(input) do
    input
    |> String.split("\n", trim: true)
    |> Enum.map(&String.split(&1, " ") |> Enum.map(fn x -> String.to_integer(x) end))
    |> Enum.filter(&safe_report?/1)
    |> length()
  end

  defp safe_report?(report) do
    differences = Enum.chunk_every(report, 2, 1, :discard) |> Enum.map(fn [a, b] -> b - a end)
    increasing = Enum.all?(differences, &(&1 in 1..3))
    decreasing = Enum.all?(differences, &(&1 in -3..-1))
    increasing or decreasing
  end
end

# テストデータ
input = """
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
"""

IO.puts AdventOfCode2024Day2Part1.count_safe_reports(input)

Part 2

defmodule AdventOfCode2024Day2Part2 do
  def count_safe_reports(input) do
    input
    |> String.split("\n", trim: true)
    |> Enum.map(fn line -> String.split(line, " ") |> Enum.map(&String.to_integer/1) end)
    |> Enum.filter(&safe_report_with_dampener?/1)
    |> length()
  end

  defp safe_report_with_dampener?(report) do
    safe_report?(report) or Enum.any?(0..(length(report) - 1), fn i ->
      safe_report?(List.delete_at(report, i))
    end)
  end

  defp safe_report?(report) do
    differences = Enum.chunk_every(report, 2, 1, :discard) |> Enum.map(fn [a, b] -> b - a end)
    increasing = Enum.all?(differences, &(&1 in 1..3))
    decreasing = Enum.all?(differences, &(&1 in -3..-1))
    increasing or decreasing
  end
end

# テストデータ
input = """
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
"""

IO.puts AdventOfCode2024Day2Part2.count_safe_reports(input)