52 lines
1.1 KiB
Elixir
52 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
|