Advent of Code 2024 - Day 3
Code for Day 03
Wow. After Day 2 pt 2, I was sure I’d be cooked and not be able to continue on. Oh how wrong Greg from a 4 hours ago was.
Today’s challenge involves filtering through “corrupted data” looking for recognizable operations and performing them.
I didn’t even bother with a separate file, instead wrote each solver in tests.
Part 1
For part 1 - the only operation needed is mul(x,y)
- X and Y are numbers to multiply together. Then summing the product.
test('pt1 sample dataset', () => {
const input = `xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))`
const matcher = /mul\((?<a>\d+),(?<b>\d+)\)/gm
const matches = input.matchAll(matcher)
let sum = 0
for (const match of matches) {
const group = match.groups
sum = sum + (Number(group.a) * Number(group.b))
}
assert.equal(sum, 188192787)
})
If you know RegEx the solution is easy. We can use it to find the data to multiply together as groups and then iterate over the iterator collections adding up the multiplications.
Part 2
Part 2 introduced 2 new “uncorrupted” operations to pay attention to.
don't()
and do()
They act as flags to disable and enable future operations.
The default state is to perform the operations
We can think in terms of gating or switching to understand the logic.
test('pt2 sample dataset', async t => {
const input = `xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))`
const matcher = /(mul\((?<a>\d+),(?<b>\d+)\)|(?<dont>don't\(\))|(?<do>do\(\)))/gm
const matches = input.matchAll(matcher)
let enabled = true
let sum = 0
for (const match of matches) {
const group = match.groups
if (group.dont) {
enabled = false
continue
}
if (group.do) {
enabled = true
continue
}
if (enabled) {
sum = sum + (Number(group.a) * Number(group.b))
}
}
assert.equal(sum, 48)
})
An adjustment to the RegEx from Part 1 is needed
- Wrapping the whole matcher in a group
- Use
|
to define alternate group matchers fordon't()
anddo()
This gives a Regex pattern that has 3 possible matches for the group.
Once the matcher is run against the input, the output is an iterator with each group in sequence. Meaning there will be either a mul
, don't()
, do()
in each step of the iterator, sequentially matching the input.
- Starting with
mul
enabled - Step through each match
- If enabled ===
true
and the match ismul
- perform multiplication and add the product to the sum - If the match is
don't()
set enabled to false - If the match is
do
set enabled to true
This code is easy enough to understand without much documentation on the operations that someone without regex experience should be able to understand and alter (assuming they do not look at the matcher). However the regex itself is also easy to understand, that a quick visit to Regex101 will describe it in detail and provide a playground to test against.
Overall, I feel relieved and elated that Day 3 challenge wasn’t such a struggle as Day 2.
Takeaway from today
ALWAYS BET ON REGEX
(unless to parse email, then avoid.)