Trebuchet?!
Robert Mion
Posted on December 1, 2023
Advent of Code 2023 Day 1
Part 1
Three steps - at least as I see it
- A regular expression to find the digits
- Extracting the matches at the book ends
- Coercing, summing and reducing
Let's get to it!
A regular expression to find the digits
a1b2c3d4e5f
I need a regular expression that matches only the five digits 1-5
in the string above.
Thankfully, that's as simple as:
/\d/g
Extracting the matches at the book ends
Once I have the list of matches, I want the first and last ones only, event if they are the same from having only one digit in the string:
matches[0] , matches[matches.length - 1]
Coercing, summing and reducing
Then I need to coerce each match to numbers and fuse them together into a two-digit number:
+(matches[0] + matches[matches.length - 1])
Lastly, this can all fit nicely in a larger reduce
r function that iterates through the full input:
For each input string, accumulate a number starting at 0
Find all digits in the string
Extract the first and last matches
Fuse them together into a two-digit number
Return the sum of the accumulated number and this two-digit number
Return the accumulated sums
Altogether, in JavaScript
input.split('\n').reduce(
(sums, text) => {
const matches = [...text.matchAll(/\d/g)].map(el => el[0])
return sums + +(matches[0] + matches[matches.length - 1])
}, 0
)
It generates the correct answer for the example input!
Confirming it works before submitting
This is what I see when running the algorithm on a few lines of my input:
[ '4' ] 44
[ '2' ] 22
[ '6' ] 66
[ '4' ] 44
[ '5' ] 55
[ '5', '2' ] 52
[ '1', '3', '7', '8', '1' ] 11
[ '8' ] 88
[ '4', '3', '1' ] 41
[ '6', '2', '2', '3' ] 63
It successfully doubles the single digits, and fuses together the first and last digits!
Getting excited for Part 2
A quick glance at my input revealed some numbers spelled out:
gtjtwonefourone6fouronefccmnpbpeightnine
one one one nine
four four eight
I wonder if part two will pose the same challenge, but using the spelled out words instead of the digits?!
Submitting my answer to Part 1
It was correct!
Part 2
I was right!...and then some!
Part 2 does require using the spelled out numbers.
But in addition to - not instead of - the digits!
Hmmm, this...just...got...trickier.
Matching the spelled out numbers
Seems like there's no way to avoid a legend:
['one','two','three','four',...,'nine']
Or is there...?
Could I do this with a regular expression, still?
/one|two|three|four|five|six|seven|eight|nine|\d/g
It works!
But how will I convert words to numbers before fusing or doubling?
Turning words into numbers when necessary
How about a dictionary a.k.a. object?
one: 1,
two: 2,
three: 3,
...
nine: 9
I'll need to check the matched string for whether it is a number:
if (isNaN(match))
look-up in dictionary
else
already a number
All of that, in pseudocode
Set dictionary mapping words to digits
For each input string, accumulate a number starting at 0
Find all numbers - word or digit - in the string
Extract the first and last matches
If either match is a word
Convert word to digit
Fuse them together into a two-digit number
Return the sum of the accumulated number and this two-digit number
Return the accumulated sums
Now, in JavaScript
const dict = { 'one': '1', 'two': '2', ... }
input.split('\n').reduce((sums, text) => {
const regex = /one|two|three|four|five|six|seven|eight|nine|\d/g
const matches = [...text.matchAll(regex)].map(el => el[0])
let [first, last] = [matches[0], matches[matches.length - 1]]
if (isNaN(first)) first = dict[first]
if (isNaN(last)) last = dict[last]
return sums + +(first + last)
}, 0)
Checking and submitting
It works on the example input!
The console shows the expected extractions for each line.
It generated the correct answer for my input, too!
Lovin' me some regex
I'm so glad I took the time to learn and practice regex
in earlier AoC challenges.
Regexr has been an invaluable tool as a beginner.
I'd hate to imagine being a beginner and trying today's challenge!
If that's you, I hope you find this series helpful and validation that you too can go from CS newbie to near-expert solver (except for shortest-path and performance-based algorithms) with enough practice, persistence and patience.
And now we wait for Day 2 to unlock...
Posted on December 1, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.