defmodule Day1 do def get_answer({_, total, :part1}), do: total def get_answer({_, totals, :part2}), do: totals |> Enum.reduce(0, fn i, acc -> i + acc end) def init_state(:part1 = p), do: {nil, 0, p} def init_state(:part2 = p), do: {nil, [0, 0, 0], p} def execute(line, state) do line |> to_command() |> apply_command(state) end defp apply_command({:add, n}, state), do: apply_add(n, state) defp apply_command({:reset}, state), do: apply_reset(state) defp to_command(s) do try do {:add, s |> String.trim() |> String.to_integer()} rescue ArgumentError -> {:reset} end end defp apply_add(n, {nil, total, part}), do: {n, total, part} defp apply_add(n, {current, total, part}), do: {n + current, total, part} defp take_top_three(n, list) do [n | list] |> Enum.sort(:desc) |> Enum.take(3) end defp apply_reset({nil, _, _} = state), do: state defp apply_reset(state) do {current, total, part} = state case part do :part1 -> {nil, max(total, current), part} :part2 -> {nil, take_top_three(current, total), part} end end end