Regexp solution for Advent for Code 2024 Day 3

Hi everyone, I’m having trouble implementing a regex solution for Day 3 of Advent for Code 2024.

The goal is to find all the sub-strings that have the pattern mul(X,Y) with X,Y being 1 to 3 digit integers. Since I want to extract these two integers, I want to put them in parentheses. I therefore used this regexp:

let valid_mul_instruction = Str.regexp {|mul(\([0-9][0-9]?[0-9]?\),\([0-9][0-9]?[0-9]?\))|}

which is used in this function

let compute_mul_instructions str =
  let rec find_matches pos acc =
    try
      let new_pos = Str.search_forward valid_mul_instruction str pos in
      let match_str = Str.matched_string str in
      let factor1 = int_of_string (Str.matched_group 1 match_str) in
      let factor2 = int_of_string (Str.matched_group 2 match_str) in
      find_matches (new_pos + String.length match_str) (acc + factor1 * factor2)
    with Not_found ->
      acc
  in
  find_matches 0 0

But given the example mul(241,176), Str.matched_group 1 match_str returns 41,. Is there something wrong with the group parentheses in the regexp?

How about using

let scan str = Scanf.sscanf str "mul(%d,%d)" (fun x y -> (x,y))

and testing the properties of x and y of being in range [0,999] later rather than doing this syntactically?

1 Like

Scanf is able to express this directly with mul(%3u,%3u) (although FWIW I think ocamllex is a better fit here, as it gives a compiled automaton which ought to have better backtracking performance, though that shouldn’t matter for this AoC problem!)

1 Like

You should write Str.matched_group 1 str not match_str.

The Str regex API is not purely functional with an hidden state. I prefer the re library.