|
| 1 | +defmodule AdventOfCode.Day07 do |
| 2 | + defp parse_input(input) do |
| 3 | + String.split(input, "\n", trim: true) |
| 4 | + |> Enum.map(fn line -> String.split(line, ":", trim: true) end) |
| 5 | + |> Enum.map(fn [value, raw_list] -> |
| 6 | + {String.to_integer(value), |
| 7 | + String.split(raw_list, " ", trim: true) |
| 8 | + |> Enum.map(fn raw_val -> String.to_integer(raw_val) end)} |
| 9 | + end) |
| 10 | + end |
| 11 | + |
| 12 | + defp join_numbers(a, b), do: Integer.pow(10, length(Integer.digits(b, 10))) * a + b |
| 13 | + |
| 14 | + @default_options [concat: true] |
| 15 | + defp is_possible?(value, numbers, options \\ []) |
| 16 | + defp is_possible?(value, [head1, head2 | tail], options) do |
| 17 | + options = Keyword.merge(@default_options, options) |
| 18 | + is_possible?(value, [head1 + head2 | tail], options) || |
| 19 | + is_possible?(value, [head1 * head2 | tail], options) || |
| 20 | + (options[:concat] && is_possible?(value, [join_numbers(head1, head2) | tail])) |
| 21 | + end |
| 22 | + defp is_possible?(value, [head1], _options), do: value == head1 |
| 23 | + |
| 24 | + def part1(input) do |
| 25 | + parse_input(input) |
| 26 | + |> Enum.filter(fn {value, numbers} -> is_possible?(value, numbers, concat: false) end) |
| 27 | + |> Enum.reduce(0, fn {value, _}, acc -> value + acc end) |
| 28 | + end |
| 29 | + |
| 30 | + def part2(input) do |
| 31 | + parse_input(input) |
| 32 | + |> Enum.filter(fn {value, numbers} -> is_possible?(value, numbers) end) |
| 33 | + |> Enum.reduce(0, fn {value, _}, acc -> value + acc end) |
| 34 | + end |
| 35 | +end |
0 commit comments