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

Day 9: Mirage Maintenance

day-9.livemd

Day 9: Mirage Maintenance

Part one

sample_input =
  """
  0 3 6 9 12 15
  1 3 6 10 15 21
  10 13 16 21 30 45
  """
defmodule MirageMaintenance do
  def sum_extrapolated_values(report, mode \\ :forward) when mode in ~w(forward backward)a do
    report
    |> parse_report()
    |> Enum.map(fn report -> extrapolate(report, mode) end)
    |> Enum.sum()
  end

  defp parse_report(report) do
    report
    |> String.split("\n", trim: true)
    |> Enum.map(fn line ->
      String.split(line, " ", trim: true) |> Enum.map(&String.to_integer/1)
    end)
  end

  defp extrapolate(numbers, mode) do
    case mode do
      :forward -> [Enum.reverse(numbers)]
      :backward -> [numbers]
    end
    |> build_rows()
    |> extrapolate_rows()
  end

  defp extrapolate_rows(rows), do: rows |> Enum.map(&hd/1) |> Enum.sum()

  defp build_rows([last_row | _] = rows) do
    if Enum.all?(last_row, &(&1 == 0)) do
      rows
    else
      new_row =
        last_row
        |> Enum.chunk_every(2, 1, :discard)
        |> Enum.map(fn [a, b] -> a - b end)

      [new_row | rows]
      |> build_rows()
    end
  end
end
MirageMaintenance.sum_extrapolated_values(sample_input)
# expected 114
Path.join(__DIR__, "day-9.input")
|> File.read!()
|> MirageMaintenance.sum_extrapolated_values()

# 1853145119

Part two

MirageMaintenance.sum_extrapolated_values(sample_input, :backward)

# expected 2
Path.join(__DIR__, "day-9.input")
|> File.read!()
|> MirageMaintenance.sum_extrapolated_values(:backward)

# 923