|
| 1 | +"""Day 6: Tuning Trouble |
| 2 | +
|
| 3 | +This module provides the solution for Advent of Code 2022 - Day 6. |
| 4 | +
|
| 5 | +It handles detecting start-of-packet and start-of-message markers in a |
| 6 | +datastream by finding sequences of unique characters. |
| 7 | +
|
| 8 | +The module contains a Solution class that inherits from SolutionBase and implements |
| 9 | +methods to identify the first position where all characters in a sliding window are distinct. |
| 10 | +""" |
| 11 | + |
| 12 | +from aoc.models.base import SolutionBase |
| 13 | + |
| 14 | + |
| 15 | +class Solution(SolutionBase): |
| 16 | + """Detect signal markers in communication device datastream. |
| 17 | +
|
| 18 | + This solution processes a datastream buffer to locate signal markers. |
| 19 | + Part 1 finds the start-of-packet marker (4 distinct characters), while |
| 20 | + Part 2 finds the start-of-message marker (14 distinct characters). |
| 21 | +
|
| 22 | + The solution uses a sliding window approach with set operations to |
| 23 | + efficiently identify positions where all characters are unique. |
| 24 | + """ |
| 25 | + |
| 26 | + def find_signal(self, data: list[str], length: int) -> int | None: |
| 27 | + """Find position after first occurrence of unique character sequence. |
| 28 | +
|
| 29 | + Uses a sliding window to scan the datastream and identifies the first |
| 30 | + position where the previous 'length' characters are all distinct. |
| 31 | +
|
| 32 | + Args: |
| 33 | + data: List containing single string of datastream characters |
| 34 | + length: Number of distinct characters required for signal marker |
| 35 | +
|
| 36 | + Returns |
| 37 | + ------- |
| 38 | + int: Number of characters processed when marker is first detected |
| 39 | + (position after the last character of the marker sequence) |
| 40 | + """ |
| 41 | + data = list(data[0]) |
| 42 | + for idx in range(len(data)): |
| 43 | + if idx >= length: |
| 44 | + signal = data[idx - length : idx] |
| 45 | + if len(set(signal)) == length: |
| 46 | + return idx |
| 47 | + |
| 48 | + return None |
| 49 | + |
| 50 | + def part1(self, data: list[str]) -> int | None: |
| 51 | + """Detect start-of-packet marker (4 unique characters). |
| 52 | +
|
| 53 | + Finds the position after the first sequence of 4 distinct characters |
| 54 | + in the datastream, indicating the device can begin packet reception. |
| 55 | +
|
| 56 | + Args: |
| 57 | + data: List of input strings to be processed |
| 58 | +
|
| 59 | + Returns |
| 60 | + ------- |
| 61 | + int: Number of characters processed before start-of-packet marker |
| 62 | + is detected |
| 63 | + """ |
| 64 | + return self.find_signal(data, 4) |
| 65 | + |
| 66 | + def part2(self, data: list[str]) -> int | None: |
| 67 | + """Detect start-of-message marker (14 unique characters). |
| 68 | +
|
| 69 | + Finds the position after the first sequence of 14 distinct characters |
| 70 | + in the datastream, indicating the device can begin message reception. |
| 71 | +
|
| 72 | + Args: |
| 73 | + data: List of input strings to be processed |
| 74 | +
|
| 75 | + Returns |
| 76 | + ------- |
| 77 | + int: Number of characters processed before start-of-message marker |
| 78 | + is detected |
| 79 | + """ |
| 80 | + return self.find_signal(data, 14) |
0 commit comments