Advent of Code 2023 Day 19
Part 1
This will be work, for sure
But doable work.
I see how I will get it done.
And that's promising, given it's Day 19 and I am not professionally trained in Computer Science.
I predict earning one star for the checkpoint that is Part 1.
But not earning a star for what will likely be the real challenge in Part 2.
Parsing the input
There are two sections.
First section has lines like this:
px{a<2006:qkq,m>2090:A,rfg}
I'll break that into these parts:
key{condition1,condition2,conditionN,fallback}
And each condition into these parts:
attribute comparison key
The trickiest parts will probably be:
- Setting up the conditions
- Walking down the condition line until a winner is found or the fallback
The second section has lines like this:
{x=787,m=2655,a=1222,s=2876}
That's a straightforward regex
:
/(\w)=(\d+)/g
-
(\w)
matches any word characters and saves it as a capture group -
=
matches an equal sign -
(\d+)
matches any digit characters and saves it as a capture group
I'll transform each line into object:
[
{
x: 787,
m: 2655,
a: 1222,
s: 2876
},
{},
...
]
And iterate through each one, processing each workflow key as the part gets reassigned until it eventually Rejects
or is Accepted
.
Ultimately, I'll use reduce
to accumulate the rating numbers for each accepted part.
To the regex
ing!
Using regex
to build the parts list
Here's my JavaScript algorithm:
parts.split('\n').map(
part => [...part.matchAll(/(\w)=(\d+)/g)]
.reduce(
(obj, RA) => {
obj[RA[1]] = +RA[2]
return obj
}, {})
)
Some clarifications:
- I use
reduce
to build the object I described above - I use
RA[1]
andRA[2]
to reference my capture groups
Using several regex
to build the workflows
One small step at a time.
To extract the key and the conditions:
/^(\w+){(.+)}/g
-
^(\w+)
matches the word characters at the beginning of the string and stores them as a capture group -
(.+)
matches all characters between the{
and}
and stores them as a capture group
To extract all four parts of the each condition:
/(\w)([<>])(\d+):(\w+)/g
From there, it's just some standard method work to arrive at a key-value pair that mimics this spec:
px: [
{ attr: 'a', cond: '<', amt: 2006, dest: 'qkq' },
{ attr: 'm', cond: '>', amt: 2090, dest: 'A' },
'g'
]
At this point, I have my parts list and my flows dictionary with each key having the ordered list of criteria.
It's time to build the workflow processor!
Writing the code that processes parts
Well that took a lot longer than expected...but for all the wrong reasons.
I use:
- Nested
while
loops - A
switch
to handle the<
and>
- A few conditions to check the current index and whether the destination is an
A
orR
- All inside a
reduce()
I got unexpectedly confused several times:
- I inadvertently only saved the last letter of the fallback destination
- I dimwittedly used bracket syntax to access an object's property, but using the actual property name and not a variable name...so I should have used the dot accessor syntax
- I failed to account for use cases where a condition's destination is
A
orR
- and my workflows dictionary doesn't haveA
orR
keys!
Anyway, an hour and a half later, my algorithm is successfully sending each part to the correct A
and R
buckets.
Now I just need to count up the part ratings!
I hope!
Calculating accepted part ratings
Well that was a lot easier:
let rating = 0
if (now == 'A') {
rating += Object.values(part).reduce((a,c) => a + c)
}
return sum += rating
It generated the correct answer for the example input!
Time for the moment of truth...
...my puzzle input...
...
...
Correct answer!!!
Woohoo!!!
How big of a scale will Part 2 be?
Part 2
Nope.
That's a massive number for the example's answer.
I'm not about to spend time analyzing the flows for some secret pattern.
Especially when I'm convinced there's an intended solve method that I'm not privy to.
I set out for one gold star.
And I earned it.
Job done here!
Top comments (0)