Untitled notebook
Mix.install([
{:kino, "~> 0.14.2"}
])
Section
instructions = Kino.Input.textarea("instructions")
Part 1
pattern = ~r/mul\((?\d+),(?\d+)\)/
instructions
|> Kino.Input.read()
|> then(&Regex.scan(pattern, &1, capture: :all))
|> Enum.map(fn [_full_pattern, l, r] ->
String.to_integer(l) * String.to_integer(r)
end)
|> Enum.sum()
Part 2
defmodule Part2 do
@moduledoc "I wanted to use python for today but part 2 was much better suited to Elixir"
@pattern ~r/\Amul\((?\d+),(?\d+)\)/
def running(""), do: 0
def running("don't()" <> rest) do
not_running(rest)
end
def running("mul(" <> rest = text) do
with %{"l" => l, "r" => r} <- Regex.named_captures(@pattern, text),
{left, ""} <- Integer.parse(l),
{right, ""} <- Integer.parse(r) do
left * right + running(rest)
else
_ -> running(rest)
end
end
def running(<<_::utf8>> <> rest), do: running(rest)
def mul_first_digit("," <> rest, digits), do: {parse_digits(digits), rest}
def mul_first_digit(<> <> rest, digits) do
mul_first_digit(rest, [<> | digits])
end
def mul_second_digit(")" <> rest, digits), do: {parse_digits(digits), rest}
def mul_second_digit(<> <> rest, digits) do
mul_first_digit(rest, [<> | digits])
end
def not_running(""), do: 0
def not_running("do()" <> rest), do: running(rest)
def not_running(<<_::utf8>> <> rest), do: not_running(rest)
def parse_digits(iolist) do
iolist
|> Enum.reverse()
|> IO.iodata_to_binary()
|> String.to_integer()
end
end
instructions
|> Kino.Input.read()
|> Part2.running()