46 lines
978 B
Elixir
46 lines
978 B
Elixir
defmodule AOC.Day9 do
|
|
@preamble_len 25
|
|
|
|
def find_invalid(queue, [hd | tl]) do
|
|
sums =
|
|
:queue.to_list(queue)
|
|
|> Combination.combine(2)
|
|
|> Enum.map(&Enum.sum/1)
|
|
|
|
queue =
|
|
:queue.in(hd, queue)
|
|
|> :queue.drop()
|
|
|
|
if hd in sums do
|
|
find_invalid(queue, tl)
|
|
else
|
|
hd
|
|
end
|
|
end
|
|
|
|
def find_weakness(invalid, [_ | tl] = nums) do
|
|
result =
|
|
Enum.reduce_while(nums, {0, []}, fn num, {sum, l} ->
|
|
sum = sum + num
|
|
if sum < invalid, do: {:cont, {sum, [num | l]}}, else: {:halt, {sum, l}}
|
|
end)
|
|
|
|
case result do
|
|
{sum, l} when sum == invalid -> Enum.min_max(l)
|
|
_ -> find_weakness(invalid, tl)
|
|
end
|
|
end
|
|
|
|
def parts do
|
|
input = AOC.Util.input_integers(9, 1)
|
|
{preamble, nums} = Enum.split(input, @preamble_len)
|
|
|
|
invalid =
|
|
preamble
|
|
|> :queue.from_list()
|
|
|> find_invalid(nums)
|
|
|
|
{min, max} = find_weakness(invalid, input)
|
|
{invalid, min + max}
|
|
end
|
|
end
|