Advent of code 2024 - Day 7
Mix.install([
{:kino, "~> 0.14.2"}
])
Part 1
https://adventofcode.com/2024/day/7
textarea = Kino.Input.textarea("Give input:")
equations =
Kino.Input.read(textarea)
|> String.split("\n", trim: true)
|> Enum.map(fn line -> [total, values_line] = String.split(line, ": ")
{ String.to_integer(total), Enum.map(String.split(values_line), &String.to_integer/1) }
end)
:ok
defmodule Solve do
defp wrap_single_list([not_a_list | r]) when not is_list(not_a_list), do: [[not_a_list | r]]
defp wrap_single_list(list_of_list), do: list_of_list
defp equation(_total, [], _oper), do: []
defp equation(total, [total], oper), do: Enum.reverse(oper)
defp equation(_total, [_val], _oper), do: []
defp equation(total, [val1, val2 | other], oper) do
plus = equation(total, [val1 + val2 | other], ["+" | oper])
multi = equation(total, [val1 * val2 | other], ["*" | oper])
if plus != [] and multi != [] do
# two solutions
wrap_single_list(plus) ++ wrap_single_list(multi)
else
plus ++ multi
end
end
def equation({total, values}), do: equation(total, values, [])
end
["*", "*"] = Solve.equation({45, [3, 5, 3]})
["+", "*"] = Solve.equation({24, [3, 5, 3]})
["*", "+"] = Solve.equation({18, [3, 5, 3]})
[] = Solve.equation({19, [3, 4, 5]})
[["+", "*"], ["*", "+"]] = Solve.equation({3267, [81, 40, 27]})
[["*", "+", "*", "*", "+"], ["*", "*", "+", "*", "+"]] =
Solve.equation({6537, [1, 81, 40, 27, 2, 3]})
# [["*", "+", "*", "*", "+"], ["*", "*", "+", "*", "+"]] =
[["+", "*", "*", "*"], ["*", "*", "*", "*"]] = Solve.equation({48, [2, 2, 2, 3, 2]})
[
["+", "+", "*", "+", "+", "+", "*", "+", "*", "*", "*"],
["*", "*", "+", "+", "+", "*", "+", "+", "+", "*", "*"],
["*", "*", "+", "+", "+", "*", "+", "+", "*", "+", "*"]
] = Solve.equation({6174, [5, 4, 3, 11, 9, 9, 7, 4, 401, 1, 1, 6]})
Enum.filter(equations, fn equation -> Solve.equation(equation) != [] end)
|> Enum.map(fn {total, _values} -> total end)
|> Enum.sum()
Part 2
defmodule SolvePart2 do
defp wrap_single_list([not_a_list | r]) when not is_list(not_a_list), do: [[not_a_list | r]]
defp wrap_single_list(list_of_list), do: list_of_list
defp equation(_total, [], _oper), do: []
defp equation(total, [total], operation_list), do: Enum.reverse(operation_list)
defp equation(_total, [_val], _oper), do: []
# when negative numbers and 0 are not in the input, apply this optimalization:
# defp equation(total, [val | _other], _oper) when val > total, do: []
defp equation(total, [val1, val2 | other], oper) do
plus = equation(total, [val1 + val2 | other], ["+" | oper])
multi = equation(total, [val1 * val2 | other], ["*" | oper])
concat =
equation(
total,
[String.to_integer(to_string(val1) <> to_string(val2)) | other],
["|" | oper]
)
solutions = Enum.filter([plus, multi, concat], fn operation_list -> operation_list != [] end)
if Enum.count(solutions) == 1 do
[operation_list] = solutions
operation_list
else
Enum.map(solutions, &wrap_single_list/1) |> Enum.reduce([], fn x, acc -> x ++ acc end)
end
end
def equation({total, values}), do: equation(total, values, [])
end
["|"] = SolvePart2.equation({156, [15, 6]})
[
["*", "*", "+", "+", "+", "*", "+", "+", "*", "+", "*"],
["*", "*", "+", "+", "+", "*", "+", "+", "+", "*", "*"],
["+", "+", "*", "+", "+", "+", "*", "+", "*", "*", "*"]
] = SolvePart2.equation({6174, [5, 4, 3, 11, 9, 9, 7, 4, 401, 1, 1, 6]})
Enum.filter(equations, fn equation -> SolvePart2.equation(equation) != [] end)
|> Enum.map(fn {total, _values} -> total end)
|> Enum.sum()