Advent of Code '24 — Day 3
Day three! Back on easy street.
Today's puzzle was about parsing a set of corrupted instructions, and extracting the good instructions. Then "executing" them and summing the results.
Part 1
Extracting the corrupted instructions. Correct instructions look like mul(x,y)
where x
and y
are up 1-3 digit numbers. Any other instruction is corrupt and invalid.
E.g. given:
xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))
Only:
mul(2,4)
mul(5,5)
mul(11,8)
mul(8,5)
Are valid, and when all multiplications are added up, we would get 161
.
This one could have gone one of two ways ;)
I did start writing a parser and a lexer to turn the input string in to an AST, and then do the math™.
But regex is much easier. So I quickly abandoned the first approach, in favour of:
PATTERN = /mul[(](\d{1,3}),(\d{1,3})[)]/i
def part1(input)
muls = input.first.scan(PATTERN)
muls.map do |pair|
Integer(pair[0]) * Integer(pair[1])
end.sum
end
First up, defining a pattern to match our good instructions. Then, mapping over them, extracting the 2 values and multiplying before adding everything up.
⭐️ Success!
Part 2
In part 2, we found out that there are conditionals still intact in the instruction set. These take the form of do
s and don't
s. When there is a do
, all subsequent instructions are to be evaluated. When there is a don't
, all future instructions are to be skipped, until the next do
.
Again, would have been really nice with an AST, but also, super quick with an update to our regex.
Now we also care about our conditional statements in the instructions, so let's grab those:
PATTERN_TWO = /mul[(](\d{1,3}),(\d{1,3})[)]|(don[']t)|(do)/i
Making sure to grab the don't
s first, so we don't accidentally confuse it for a do
.
def part2(input)
should_multiply = true
isns = input.first.scan(PATTERN_TWO)
isns
.map(&:compact)
.map do |vals|
case vals.first
when "don't"
should_multiply = false
nil
when "do"
should_multiply = true
nil
else
if should_multiply
Integer(vals[0]) * Integer(vals[1])
else
0
end
end
end
.compact
.sum
end
Then, we can extract our instructions, and iterate over them, only multiplying pairs of numbers when we previously saw a do
.
⭐️ Success!
Performance
Pretty quick again, though our input was also pretty small again today.
day 03
├─ part 1 — 0.000221s
╰─ part 2 — 0.000444s
Day three: https://github.com/dNitza/advent-of-code/tree/main/2024/03
in posts
Tagged