51 lines
1.1 KiB
Elixir
51 lines
1.1 KiB
Elixir
defmodule AOC.Day9 do
|
|
use AOC.Day, day: 9
|
|
|
|
def parse_input(lines) do
|
|
Enum.map(lines, fn line ->
|
|
line
|
|
|> String.split(" ")
|
|
|> Enum.map(&String.to_integer/1)
|
|
end)
|
|
end
|
|
|
|
def part1(histories) do
|
|
histories
|
|
|> Enum.map(&predict_next_value/1)
|
|
|> Enum.sum()
|
|
end
|
|
|
|
def part2(histories) do
|
|
Enum.map(histories, &predict_previous_value/1)
|
|
|> Enum.sum()
|
|
end
|
|
|
|
def predict_next_value(history) do
|
|
history
|
|
|> generate_differences()
|
|
|> Enum.map(&List.last/1)
|
|
|> Enum.sum()
|
|
end
|
|
|
|
def predict_previous_value(history) do
|
|
history
|
|
|> generate_differences()
|
|
|> Enum.map(&List.first/1)
|
|
|> Enum.reduce(&Kernel.-/2)
|
|
end
|
|
|
|
def generate_differences(history), do: generate_differences(history, [history])
|
|
|
|
def generate_differences(numbers, acc) do
|
|
if Enum.all?(numbers, &(&1 == 0)) do
|
|
acc
|
|
else
|
|
differences =
|
|
numbers
|
|
|> Enum.chunk_every(2, 1, :discard)
|
|
|> Enum.map(fn [val1, val2] -> val2 - val1 end)
|
|
|
|
generate_differences(differences, [differences | acc])
|
|
end
|
|
end
|
|
end
|