DEV Community

Cover image for Aplenty
Robert Mion
Robert Mion

Posted on

Aplenty

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}
Enter fullscreen mode Exit fullscreen mode

I'll break that into these parts:

key{condition1,condition2,conditionN,fallback}
Enter fullscreen mode Exit fullscreen mode

And each condition into these parts:

attribute comparison key
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode

That's a straightforward regex:

/(\w)=(\d+)/g
Enter fullscreen mode Exit fullscreen mode
  • (\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
  },
  {},
  ...
]
Enter fullscreen mode Exit fullscreen mode

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 regexing!

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
    }, {})
)
Enter fullscreen mode Exit fullscreen mode

Some clarifications:

  • I use reduce to build the object I described above
  • I use RA[1] and RA[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
Enter fullscreen mode Exit fullscreen mode
  • ^(\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
Enter fullscreen mode Exit fullscreen mode

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'
  ]
Enter fullscreen mode Exit fullscreen mode

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 or R
  • 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 or R - and my workflows dictionary doesn't have A or R 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
Enter fullscreen mode Exit fullscreen mode

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)