Day 2
Mix.install([:kino])
Read File
file_value = Kino.Input.file("Please Select Input File")
file_input = Kino.Input.read(file_value)
file_path = Kino.Input.file_path(file_input.file_ref)
contents = File.read!(file_path)
reports =
contents
|> String.split("\n")
|> Enum.map(fn line -> String.split(line, " ") end)
|> Enum.map(fn numbers ->
numbers
|> Enum.reject(fn n -> String.length(n) == 0 end)
|> Enum.map(&String.to_integer/1)
end)
|> Enum.reject(&Enum.empty?/1)
defmodule ReportEvaluator do
defstruct last: nil, direction: nil, max_difference: 3
def run(numbers) when is_list(numbers),
do: run(%ReportEvaluator{}, numbers)
def run(_state, []),
do: true
def run(%ReportEvaluator{last: nil} = state, [n | t]),
do: run(%{state | last: n}, t)
def run(%ReportEvaluator{last: m, max_difference: max}, [n | _]) when n > m and n - m > max,
do: false
def run(%ReportEvaluator{last: m, max_difference: max}, [n | _]) when m > n and m - n > max,
do: false
def run(%ReportEvaluator{last: m, direction: nil} = state, [n | t]) when n > m,
do: run(%{state | direction: :asc, last: n}, t)
def run(%ReportEvaluator{last: m, direction: nil} = state, [n | t]) when n < m,
do: run(%{state | direction: :desc, last: n}, t)
def run(%ReportEvaluator{last: n}, [n | _]),
do: false
def run(%ReportEvaluator{last: m, direction: :asc}, [n | _]) when n < m,
do: false
def run(%ReportEvaluator{last: m, direction: :desc}, [n | _]) when n > m,
do: false
def run(%ReportEvaluator{} = state, [n | t]),
do: run(%{state | last: n}, t)
end
defmodule ProblemDampener do
def run(numbers, evaluator) when is_function(evaluator, 1),
do: run(numbers, evaluator, evaluator.(numbers), 0, length(numbers))
def run(_numbers, _evaluator, true, _index, _length),
do: true
def run(_numbers, _evaluator, result, length, length),
do: result
def run(numbers, evaluator, false, index, length),
do: run(numbers, evaluator, evaluator.(List.delete_at(numbers, index)), index + 1, length)
end
Part 1
reports
|> Enum.filter(&ReportEvaluator.run/1)
|> length()
Part 2
reports
|> Enum.filter(fn numbers ->
ProblemDampener.run(numbers, &ReportEvaluator.run/1)
end)
|> length()