Advent of Code 2024 - Day 3

Thanks for your regex. It’s the first time I saw (?>pattern) in a regex.

Here’s my solution:

Part 1

~r/
  (?<=mul\()  # prefixed by "mul("  (positive lookbehind, not captured)
  (\d{1,3})   # max-3-digit number  (captured)
  ,           # matches a comma     (not captured)
  (\d{1,3})   # max-3-digit number  (captured)
  (?=\))      # suffixed by ")"     (positive lookahead, not captured)
/x
|> Regex.scan(puzzle_input, capture: :all_but_first)
|> List.flatten()
|> Enum.map(&String.to_integer/1)
|> Enum.chunk_every(2)
|> Enum.map(fn [a, b] -> a * b end)
|> Enum.sum()

Part 2

~r/
  (do\(\))     # matches "do()" (captured)
  |            # or
  (don't\(\))  # matches "don't()" (captured)
  |            # or
  (?<=mul\()(\d{1,3}),(\d{1,3})(?=\))  # matches the same pattern as in Part 1, captures only the numbers
/x
|> Regex.scan(puzzle_input, capture: :all_but_first)
|> Enum.map(fn
  ["do()"] -> :on
  ["", "don't()"] -> :off
  ["", "", a, b] -> {String.to_integer(a), String.to_integer(b)}
end)
|> Enum.reduce({0, :on}, fn
  :on, {sum, _} -> {sum, :on}
  :off, {sum, _} -> {sum, :off}
  {a, b}, {sum, :on} -> {sum + a * b, :on}
  _, acc -> acc
end)
|> elem(0)
3 Likes