Day 03
Mix.install([:kino_aoc])
Kino.configure(inspect: [charlists: :as_lists])
Input
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2024", "3", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
Part 1
# Regex version
Regex.scan(~r/mul\((\d+),(\d+)\)/, puzzle_input)
|> Enum.reduce(0, fn [_capture, l, r], acc ->
acc + String.to_integer(l) * String.to_integer(r)
end)
# Pattern matching version
defmodule Part1 do
def parse("", _state, parsed), do: parsed
def parse("mul(" <> rest, _state, parsed), do: parse(rest, :left_arg, [{"", ""} | parsed])
def parse(")" <> rest, :right_arg, parsed), do: parse(rest, :nil, parsed)
def parse("," <> rest, :left_arg, parsed), do: parse(rest, :right_arg, parsed)
def parse(<>, state, [{l, r} | tail] = parsed) when x in ?0..?9 do
case state do
:left_arg -> parse(rest, :left_arg, [{l <> <>, r} | tail])
:right_arg -> parse(rest, :right_arg, [{l, r <> <>} | tail])
_ -> parse(rest, state, parsed)
end
end
def parse(<<_x, rest::binary>>, :left_arg, [_head | tail]), do: parse(rest, nil, tail)
def parse(<<_x, rest::binary>>, :right_arg, [_head | tail]), do: parse(rest, nil, tail)
def parse(<<_x, rest::binary>>, state, parsed), do: parse(rest, state, parsed)
end
Part1.parse(puzzle_input, nil, [])
|> Enum.reduce(0, fn {l, r}, acc -> acc + String.to_integer(l) * String.to_integer(r) end)
Part 2
Regex.scan(~r/mul\((\d+),(\d+)\)|do\(\)|don't\(\)/, puzzle_input)
|> Enum.reduce({true, 0}, fn
["do()"], {_status, acc} -> {true, acc}
["don't()"], {_status, acc} -> {false, acc}
[_capture, l, r], {true, acc} -> {true, acc + String.to_integer(l) * String.to_integer(r)}
_, {false, acc} -> {false, acc}
end)
|> elem(1)