Aplenty
Tags: adventofcode, algorithms, javascript, programming
Published: 2024-02-25 02:45:04

## [Advent of Code 2023 Day 19](https://adventofcode.com/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:
```js
[
  {
    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:
```js
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]` 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:
```js
/^(\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:
```js
/(\w)([<>])(\d+):(\w+)/g
```

From there, it's just some standard method work to arrive at a key-value pair that mimics this spec:
```js
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` 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:
```js
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!