7
votes
Day 19: Aplenty
Today's problem description: https://adventofcode.com/2023/day/19
Please post your solutions in your own top-level comment. Here's a template you can copy-paste into your comment to format it nicely, with the code collapsed by default inside an expandable section with syntax highlighting (you can replace python
with any of the "short names" listed in this page of supported languages):
<details>
<summary>Part 1</summary>
```python
Your code here.
```
</details>
Today's problem was a lot of fun. I was glad for the easier problem after not having time to finish yesterday's part 2. This one reminded me a bit of day 5, what with having to use ranges for part 2. My solution ended up being pretty long, but I think it's reasonably efficient.
Solution
Everyone is saying today was fun, but idk I thought it was miserable. I had a bad representation for the ranges for a really long time, and when I finally fixed it I was just so mentally done with this shit haha
General thoughts
Today is the day I by far did the most involved custom data structures for, I had an
Instruction
class and anItem
class and aRequiredState
class. For a while,RequiredState
was a list ofRequirements
for each letter.Finally (after way too long) I realized that each RequiredState is going to be a contiguous range. Upon realizing that, this got WAY easier. I started tracking like this instead:
and updating like so:
Here's my Python code. I called it
bfs
because I thought I would but then I actually did a dfs, oh well.After yesterday's frustrating math homework, today's part 1 was great fun. Unfortunately I then proceeded to waste hours on a simple bug in part 2 that I could just not find. I hate it when that happens; you waste hours debugging everything, except the small piece of code where the bug actually is... that greatly diminished the fun.
Seems to be a theme for me this year: Figure out the correct algorithm quickly, then completely bungle its implementation.
Rust
The only slightly notable thing about this is that I abstracted the "Iterate a state transition function" into a re-usable library function after day 12. I didn't think I'd need it so soon again.
Step-by-step explanation | full code
This one was a lot of fun! I separated out the workflow parsing (using
operator.gt/lt
and simple string indexing), the part parsing (using a regex that found tuples), and the recursing (to get answers) so you can look at each individually.I had some trouble visualizing part 2 at first, so there's some good diagrams in there if you're having trouble as well!
Solution wise, A workflow is parsed into a dynamically-defined function which gets the next workflow(s) based on the input. For part 1, that's:
Python code
For part 2 I passed around a
Part
as adict[str, range]
, so its workflow runner was:Python code
Very fun today, and nothing too cursed!
Another solid day! I tried making use of record syntax a bit more, which sometimes turned out well (updating/splitting a range) and sometimes poorly (kind of frustrating to have
s
andx
in the module's namespace).In classic AoC tradition, I spent far too long investigating range overlaps, combinatorics miscalculations, etc. before realizing I was using the range
0 - 4000
instead of1 - 4000
...Part 1
Part 2
Golang solution
I'm pretty happy with this one overall. I would have had the solution pretty fast (for me) if it weren't for a fiddly bug in Part 2. There not much intermediate state to check in the problem statement, so I had to fall back to writing unit tests and simpler inputs until I found the bug.
Discussion
I had a nice set of
Workflow
,Rule
, andPart
data structures for part 1, so I was able to add aPartRange
for part 2 and extend the operations from Part 1 over the ranges.The bug I hit for Part 2 is that I was returning a map of
[outcome]PartRange
from each workflow (where outcome isA
,R
or another workflow), and I didn't take into account the fact that there might be multiple results for the same outcome. Once I converted it to a list of[outcome, PartRange]
pairs, everything else ran like clockwork.