Day 7
Mix.install([
{:kino, "~> 0.14.2"},
{:nx, "~> 0.9.2"}
])
Inputs
input_box = Kino.Input.textarea("input")
input =
input_box
|> Kino.Input.read()
|> String.split("\n")
|> Enum.map(fn line ->
[left, right] = String.split(line, ": ")
right =
right
|> String.split(" ")
|> Enum.map(&String.to_integer/1)
{String.to_integer(left), right}
end)
Part 1
defmodule FastCheck do
def check(expected, [], acc), do: acc == expected
def check(expected, _numbers, acc) when acc > expected, do: false
def check(expected, [head | tail], acc), do:
check(expected, tail, acc * head) ||
check(expected, tail, acc + head)
end
input
|> Task.async_stream(fn {expected, [acc | numbers]} ->
if FastCheck.check(expected, numbers, acc), do: expected, else: 0
end)
|> Enum.map(&elem(&1, 1))
|> Enum.sum()
Part 2
defmodule FastCheck2 do
defp num_digits(num, acc) when num > 0, do:
num_digits(div(num, 10), acc + 1)
defp num_digits(_num, acc), do: acc
defp concat_numbers(l, r), do:
(l * (10 ** num_digits(r, 0))) + r
def check(expected, [], acc), do: acc == expected
def check(expected, _numbers, acc) when acc > expected, do: false
def check(expected, [head | tail], acc), do:
check(expected, tail, acc * head) ||
check(expected, tail, acc + head) ||
check(expected, tail, concat_numbers(acc, head))
end
input
|> Task.async_stream(fn {expected, [acc | numbers]} ->
if FastCheck2.check(expected, numbers, acc), do: expected, else: 0
end)
|> Enum.map(&elem(&1, 1))
|> Enum.sum()