advent_of_code_2020/lib/days/day9.ex

61 lines
1.6 KiB
Elixir

defmodule AdventOfCode2020.Days.Day9 do
import AdventOfCode2020.Utils
def calculate_part_1(input, preamble_size) do
data =
input
|> file_to_list_break_line()
|> list_of_strings_to_int()
{preamble, data} = Enum.split(data, preamble_size)
find_wrong_value(data, preamble)
end
def calculate_part_2(input, preamble_size) do
data =
input
|> file_to_list_break_line()
|> list_of_strings_to_int()
{preamble, rest_of_data} = Enum.split(data, preamble_size)
find_wrong_value(rest_of_data, preamble)
|> find_contiguous(data)
|> calculate_weakness()
end
def find_wrong_value([hd|tail], preamble = [_ | tail_preamble]) do
if Enum.all?(preamble, fn x -> hd - x not in preamble end) do
hd
else
find_wrong_value(tail, tail_preamble ++ [hd])
end
end
def find_wrong_value([], _) do
nil
end
def find_contiguous(number, data = [_|tl]) do
find_contiguous(number, data, tl, [], 0)
end
def find_contiguous(number, [number | tl], to_check, values_acc, acc) do
find_contiguous(number, tl, to_check, values_acc, acc)
end
def find_contiguous(number, [hd | tl], to_check, values_acc, acc) do
new_acc = acc + hd
case new_acc do
new_acc when new_acc > number -> find_contiguous(number, to_check)
new_acc when new_acc < number -> find_contiguous(number, tl, to_check, [hd] ++ values_acc, new_acc)
new_acc when new_acc == number -> [hd] ++ values_acc
end
end
def find_contiguous(_, [], _, values_acc, _) do
values_acc
end
def calculate_weakness(data) do
Enum.min(data) + Enum.max(data)
end
end