Advent of Code 2024 - Day 3

Mull It Over

December 19th, 2024

Tags:Advent of CodeC++

This one is also not so bad, though that's probably because I somewhat know how to use regexes. I'm quite certain that this problem could be solved without regexes, but it's probably a lot more work for sure.

# Part 1

Here's the sample input that we're provided with:

1xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))

Within this input are valid multiplication instructions in the form of “mul(X,Y)”, where X and Y are 1-3 digit integers. We basically want to find all of these valid operations and compute the sum of products, ignoring any invalid operations. This is actually quite trivial to do with regexes. The following regex pattern will match such operations:

1mul\(\d+,\d+\)

From there, it's as simple as using a regex iterator to find all matches and summing up the products. Here's the C++ code that accomplishes this:

1#include <bits/stdc++.h>
2
3int main()
4{
5  std::ifstream input("day3_input.txt");
6  std::string line;
7  std::regex mul_regex("mul\\(\\d+,\\d+\\)");
8
9  long sum_of_products = 0;
10
11  while(std::getline(input, line))
12  {
13    auto mul_ops_begin = std::sregex_iterator(line.begin(), line.end(), mul_regex);
14    auto mul_ops_end   = std::sregex_iterator();
15
16    for (std::sregex_iterator iter = mul_ops_begin; iter != mul_ops_end; ++iter)
17    {
18      std::string mul_op = (*iter).str();
19      std::stringstream mul_op_ss(mul_op);
20      char c;
21      int num1, num2;
22      mul_op_ss >> c >> c >> c >> c >> num1 >> c >> num2 >> c;
23      
24      sum_of_products += num1 * num2;
25    }
26  }
27
28  std::cout << "sum of products: " << sum_of_products << std::endl;
29
30  input.close();
31  return 0;
32}

# Part 2

This part is slightly more involved as there are now some new operations that also have to be accounted for:

  • do() — this enables future multiplication instructions past this instruction.
  • don't() — this disables future multiplication instructions past this instruction.

Again, this is not terribly difficult if regexes are used. We simply just expand our previous regex to include the other operations as alternative matches. We then use a regex iterator to go through the matches in sequential order, keeping track of when we should or shouldn't be multiplying, and we compute the sum of products. Here's the C++ code that accomplishes this:

1#include <bits/stdc++.h>
2
3int main()
4{
5  std::ifstream input("day3_input.txt");
6  std::string line;
7  std::regex op_regex("mul\\(\\d+,\\d+\\)|do\\(\\)|don't\\(\\)");
8
9  long sum_of_products = 0;
10  bool is_multiplying = true;
11
12  while(std::getline(input, line))
13  {
14    auto ops_begin = std::sregex_iterator(line.begin(), line.end(), op_regex);
15    auto ops_end   = std::sregex_iterator();
16
17    for (std::sregex_iterator iter = ops_begin; iter != ops_end; ++iter)
18    {
19      std::string op = (*iter).str();
20      
21      if (op == "do()") 
22      {
23        is_multiplying = true;
24        continue;
25      } else if (op == "don't()")
26      {
27        is_multiplying = false;
28        continue;
29      }
30
31      if (is_multiplying) {
32        std::stringstream op_ss(op);
33
34        char c;
35        int num1, num2;
36        op_ss >> c >> c >> c >> c >> num1 >> c >> num2 >> c;
37
38        sum_of_products += num1 * num2;
39      }
40    }
41  }
42
43  std::cout << "sum of products: " << sum_of_products << std::endl;
44
45  input.close();
46  return 0;
47}

And that's basically it. It was a little trivial for me since I just used a regex to solve all my problems, but I do wonder what a non-regex-based solution might've looked like.