Advent of code day 07
Mix.install([
{:kino, "~> 0.5.0"}
])
Setup input
example = Kino.Input.textarea("Please paste your input example:")
input = Kino.Input.textarea("Please paste your real input:")
Part 01
defmodule Solver do
def possible?(target, nums) do
possible?(target, nums, 0)
end
defp possible?(t, [], sum), do: t == sum
defp possible?(t, [n | nums], sum) do
possible?(t, nums, n + sum) || possible?(t, nums, n * sum)
end
end
input =
example
|> Kino.Input.read()
|> String.split(["\n", ": "], trim: true)
|> Enum.chunk_every(2)
|> Enum.reduce(%{}, fn [target, rest], acc ->
Map.put(
acc,
String.to_integer(target),
String.split(rest) |> Enum.map(&String.to_integer(&1))
)
end)
:timer.tc(fn ->
Enum.reduce(input, 0, fn {k, v}, acc ->
case Solver.possible?(k, v) do
true -> acc + k
false -> acc
end
end)
end)
|> then(fn {time, value} ->
"it took #{div(time, 1000)} ms and result is #{value}"
end)
Part 02
defmodule Solver2 do
def possible?(target, nums) do
possible?(target, nums, 0)
end
defp possible?(t, [], sum), do: t == sum
defp possible?(t, [n | nums], sum) do
possible?(t, nums, n + sum) ||
possible?(t, nums, n * sum) ||
possible?(t, nums, sum * 10 ** digits(n) + n)
end
defp digits(n) do
Integer.to_string(n) |> String.length()
end
end
:timer.tc(fn ->
Task.async_stream(input, fn {k, v} ->
case Solver2.possible?(k, v) do
true -> k
false -> 0
end
end)
|> Enum.reduce(0, fn {:ok, n}, acc -> n + acc end)
end)
|> then(fn {time, value} ->
"it took #{div(time, 1000)} ms and result is #{value}"
end)