Advent of Code 2024-Day 25: Code Chronicle
from advent import parse, partition, cross_product
pairs = [ (schematic[0][0] == '#', [ len(partition(line, lambda c: c == line[0])[0])
for line in schematic ])
for schematic in parse(25, lambda s: list(zip(*str.split(s, '\n'))), sep='\n\n') ]
locks = [ lengths for is_lock, lengths in pairs if is_lock ]
keys = [ lengths for is_lock, lengths in pairs if not is_lock ]
pins = 5
total = sum(1 for lock, key in cross_product(locks, keys) if all([ lock[pin] <= key[pin]
for pin in range(pins) ]))
assert total == 2618
Parsing
We're given a list of schematics - either for locks or keys. For each schematic, we'll do the following:
Transpose the matrix (using zip(*...)), so the pins are horizontal instead of vertical:
Compute the length of the inital list of either . characters or # characters:
Finally, form a 2-tuple of (<boolean>, <len>) where the <boolean> indicates the schematic is a lock, and the
<len> is the length of the # characters for locks or . characters for keys:
Solution
For today, parsing the input is more than half the battle! Once we have our data structures in place via the above, we simply form a cartesian product of locks and keys, and filter the pairs by whether the key fits in the lock:
total = sum(1 for lock, key in cross_product(locks, keys) if all([ lock[pin] <= key[pin]
for pin in range(pins) ]))
Conclusion
This was a nice easy puzzle to wrap up Advent of Code 2024. I really enjoyed this years contest - it
was a fun way to become more proficient with Python and some of its ecosystem - particularly the networkx library.