|
| 1 | + |
| 2 | +from aoc.models.base import SolutionBase |
| 3 | + |
| 4 | + |
| 5 | +class Solution(SolutionBase): |
| 6 | + """Solution for Advent of Code 2024 - Day 25: Code Chronicle. |
| 7 | +
|
| 8 | + This class solves a puzzle about analyzing lock and key combinations to determine |
| 9 | + valid pairings. Each lock and key is represented as a pattern of symbols, and |
| 10 | + the solution counts how many lock-key pairs will successfully open based on their |
| 11 | + combined patterns. |
| 12 | +
|
| 13 | + Input format: |
| 14 | + - Multiple blocks separated by blank lines |
| 15 | + - Each block represents either a lock or a key pattern |
| 16 | + - Locks have 5 '#' symbols in their first row |
| 17 | + - Keys have a different number of '#' symbols in their first row |
| 18 | + - Each pattern consists of '#' and other symbols arranged in a grid |
| 19 | +
|
| 20 | + The challenge involves analyzing the height profiles of locks and keys |
| 21 | + to determine which combinations will successfully open. |
| 22 | + """ |
| 23 | + |
| 24 | + def part1(self, data: list[str]) -> int: |
| 25 | + """Count the number of valid lock-key pairs. |
| 26 | +
|
| 27 | + Parses the input to extract lock and key patterns, computes their height |
| 28 | + profiles, and then determines how many combinations satisfy the opening |
| 29 | + criteria (combined height ≤ 5 for each column). |
| 30 | +
|
| 31 | + The algorithm works by: |
| 32 | + 1. Separating the input into individual lock and key patterns |
| 33 | + 2. Converting each pattern into a height profile (count of '#' symbols per column) |
| 34 | + 3. Testing each lock-key combination to see if their combined profiles meet the criteria |
| 35 | +
|
| 36 | + Args: |
| 37 | + data: List of strings containing lock and key patterns separated by blank lines |
| 38 | +
|
| 39 | + Returns |
| 40 | + ------- |
| 41 | + Integer count of valid lock-key combinations that will successfully open |
| 42 | + """ |
| 43 | + data = "\n".join(data).split("\n\n") |
| 44 | + locks = [] |
| 45 | + keys = [] |
| 46 | + |
| 47 | + for item in data: |
| 48 | + item = item.split("\n") |
| 49 | + cols = [[row[c] for row in item] for c in range(len(item[0]))] |
| 50 | + heights = [col.count("#") - 1 for col in cols] |
| 51 | + |
| 52 | + if item[0].count("#") == 5: |
| 53 | + locks.append(heights) |
| 54 | + else: |
| 55 | + keys.append(heights) |
| 56 | + |
| 57 | + count = sum( |
| 58 | + all(c <= 5 for c in [a + b for a, b in zip(lock, key, strict=False)]) |
| 59 | + for lock in locks |
| 60 | + for key in keys |
| 61 | + ) |
| 62 | + return count |
0 commit comments