# Regexp solution for Advent for Code 2024 Day 3

**URL:** <https://discuss.ocaml.org/t/regexp-solution-for-advent-for-code-2024-day-3/15768>\
**Category:** Learning\
**Tags:** regexp\
**Created:** [December 8, 2024, 11:39am UTC](https://discuss.ocaml.org/t/regexp-solution-for-advent-for-code-2024-day-3/15768 "2024-12-08T11:39:10Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![LiDazhao](https://avatars.discourse-cdn.com/v4/letter/l/b3f665/32.png) [@LiDazhao](https://discuss.ocaml.org/u/LiDazhao)\
**Post date:** [December 8, 2024, 11:39am UTC](https://discuss.ocaml.org/t/regexp-solution-for-advent-for-code-2024-day-3/15768/1 "2024-12-08T11:39:10Z")

</div>

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:

```ocaml
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

```ocaml
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?

---

<div class="post-metadata">

**Author:** ![lindig](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lindig/32/532_2.png) [@lindig](https://discuss.ocaml.org/u/lindig)\
**Post date:** [December 8, 2024, 1:14pm UTC](https://discuss.ocaml.org/t/regexp-solution-for-advent-for-code-2024-day-3/15768/2 "2024-12-08T13:14:28Z")

</div>

How about using

```auto
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?

---

<div class="post-metadata">

**Author:** ![dra27](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dra27/32/5294_2.png) [@dra27](https://discuss.ocaml.org/u/dra27)\
**Post date:** [December 8, 2024, 4:33pm UTC](https://discuss.ocaml.org/t/regexp-solution-for-advent-for-code-2024-day-3/15768/3 "2024-12-08T16:33:24Z")

</div>

> [@lindig](#):
>
> and testing the properties of `x` and `y` of being in range [0,999] later rather than doing this syntactically?

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!)

---

<div class="post-metadata">

**Author:** ![Frederic\_Loyer](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/frederic_loyer/32/3472_2.png) [@Frederic\_Loyer](https://discuss.ocaml.org/u/Frederic_Loyer)\
**Post date:** [December 8, 2024, 6:19pm UTC](https://discuss.ocaml.org/t/regexp-solution-for-advent-for-code-2024-day-3/15768/4 "2024-12-08T18:19:15Z")

</div>

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.
