66 lines
2.1 KiB
Elixir
66 lines
2.1 KiB
Elixir
defmodule Aoc2024.Day07 do
|
|
def parse(input) do
|
|
input
|
|
|> String.split("\n", trim: true)
|
|
|> Enum.map(fn x -> x |> String.split(": ") |> Enum.into([]) end)
|
|
|> Enum.map(fn [x, y] -> {String.to_integer(x), y |> String.split(" ") |> Enum.map(&String.to_integer/1)} end)
|
|
|> Enum.into([])
|
|
end
|
|
|
|
def part1(input) do
|
|
input
|
|
|> Enum.map(fn {target, numbers} -> Task.async(fn -> compute(target, numbers) end) end)
|
|
|> Enum.map(&Task.await/1)
|
|
|> Enum.filter(&Kernel.is_integer/1)
|
|
|> Enum.sum()
|
|
end
|
|
|
|
defp compute(target, numbers), do: compute(target, Enum.reverse(numbers), target)
|
|
defp compute(_, _, current) when current < 0, do: nil
|
|
defp compute(target, [], 0), do: target
|
|
defp compute(_, _, 0), do: nil
|
|
defp compute(_, [], _), do: nil
|
|
defp compute(target, [x | numbers], current) do
|
|
if rem(current, x) == 0 do
|
|
if compute(target, numbers, div(current, x)) == target do
|
|
target
|
|
else
|
|
compute(target, numbers, current - x)
|
|
end
|
|
else
|
|
compute(target, numbers, current - x)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
def part2(input) do
|
|
input
|
|
|> Enum.map(fn {target, numbers} -> Task.async(fn -> compute2(target, numbers) end) end)
|
|
|> Enum.map(&Task.await/1)
|
|
|> Enum.filter(&Kernel.is_integer/1)
|
|
|> Enum.sum()
|
|
end
|
|
|
|
defp compute2(target, numbers), do: compute2(target, Enum.reverse(numbers), target)
|
|
defp compute2(_, _, current) when current < 0, do: nil
|
|
defp compute2(target, [], 0), do: target
|
|
defp compute2(_, _, 0), do: nil
|
|
defp compute2(_, [], _), do: nil
|
|
defp compute2(target, [x | numbers], current) do
|
|
s_c = current |> Integer.to_string()
|
|
s_x = x |> Integer.to_string()
|
|
nc = s_c |> String.replace_suffix(s_x, "")
|
|
cond do
|
|
s_c |> String.ends_with?(s_x)
|
|
and nc != ""
|
|
and compute2(target, numbers, nc |> String.to_integer()) == target ->
|
|
target
|
|
rem(current, x) == 0 and compute2(target, numbers, div(current, x)) == target ->
|
|
target
|
|
true ->
|
|
compute2(target, numbers, current - x)
|
|
end
|
|
end
|
|
end
|