Skip to content

Commit f406f12

Browse files
author
Mallory Brickerd
committed
chore: docstrings for solution and tests
1 parent a02158d commit f406f12

File tree

2 files changed

+65
-33
lines changed

2 files changed

+65
-33
lines changed

_2025/solutions/day02.py

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
"""Boilerplate solution template for Advent of Code daily challenges.
1+
"""Day 2: Gift Shop
22
3-
This module provides a template class for solving Advent of Code puzzle problems.
4-
It includes a base structure with two method stubs (part1 and part2) that can be
5-
implemented for specific day's challenges.
3+
This module provides the solution for Advent of Code 2025 - Day 2.
64
7-
The template follows the SolutionBase pattern used across the Advent of Code solutions,
8-
allowing for consistent handling of input parsing and solution execution.
5+
It identifies invalid product IDs within given ranges. An ID is considered
6+
invalid if it is formed by a repeating sequence of digits.
7+
8+
The module contains a Solution class that inherits from SolutionBase for
9+
parsing ID ranges and summing the invalid IDs found.
910
"""
1011

1112
from collections.abc import Callable
@@ -15,17 +16,28 @@
1516

1617

1718
class Solution(SolutionBase):
18-
"""Solution template for Advent of Code daily puzzle.
19+
"""Find and sum invalid product IDs based on repeating digit patterns.
1920
20-
This class provides a standardized structure for implementing solutions to
21-
daily Advent of Code challenges. It inherits from SolutionBase and includes
22-
method stubs for part1 and part2 of the puzzle.
21+
This solution processes a string of comma-separated ID ranges (e.g., "1-10,20-30").
22+
It checks each ID in every range to see if it matches a specific pattern of
23+
repeating digits.
2324
24-
Subclasses should override these methods with specific implementation logic
25-
for parsing input and solving the puzzle requirements.
25+
Part 1 defines an invalid ID as one made of a digit sequence repeated twice (e.g., 1212).
26+
Part 2 expands this to any ID made of a sequence repeated at least twice (e.g., 1212, 121212).
2627
"""
2728

2829
def has_repeated_sequence(self, n: int, num_repeats: int | None = None) -> bool:
30+
"""Check if a number consists of a repeating sequence of digits.
31+
32+
Args:
33+
n: The integer to check.
34+
num_repeats: If an integer, checks for exactly that many repetitions.
35+
If None, checks for any number of repetitions (>= 2).
36+
37+
Returns
38+
-------
39+
bool: True if the number is formed by a repeating sequence, False otherwise.
40+
"""
2941
s = str(n)
3042
length = len(s)
3143

@@ -39,6 +51,7 @@ def has_repeated_sequence(self, n: int, num_repeats: int | None = None) -> bool:
3951
size = length // num_repeats
4052
return s == s[:size] * num_repeats
4153

54+
# Check for any number of repetitions from 2 up to the length of the string
4255
for k in range(2, length + 1):
4356
if length % k == 0:
4457
size = length // k
@@ -47,37 +60,58 @@ def has_repeated_sequence(self, n: int, num_repeats: int | None = None) -> bool:
4760

4861
return False
4962

50-
def solve_part(self, data: list[str], func: Callable) -> int:
51-
invalid = 0
63+
def solve_part(self, data: list[str], func: Callable[[int], bool]) -> int:
64+
"""Generic solver to find and sum invalid IDs based on a check function.
65+
66+
Parses the input string of ranges, iterates through each number, and applies
67+
the provided checking function to identify and sum invalid IDs.
68+
69+
Args:
70+
data: A list containing one string of comma-separated ranges.
71+
func: A callable that takes an integer and returns True if it's invalid.
72+
73+
Returns
74+
-------
75+
int: The sum of all invalid product IDs found.
76+
"""
77+
invalid_sum = 0
5278
for line in data[0].split(","):
5379
start, end = map(int, line.split("-"))
54-
for product in range(start, end + 1):
55-
if func(product):
56-
invalid += product
80+
for product_id in range(start, end + 1):
81+
if func(product_id):
82+
invalid_sum += product_id
5783

58-
return invalid
84+
return invalid_sum
5985

6086
def part1(self, data: list[str]) -> int:
61-
"""Solve the first part of the daily puzzle.
87+
"""Calculate the sum of invalid IDs where a digit sequence is repeated twice.
88+
89+
An ID is invalid if it's formed by a sequence of digits repeated
90+
exactly twice (e.g., `6464` from `64`). This method sums all such
91+
IDs found in the input ranges.
6292
6393
Args:
64-
data: List of input strings to be processed
94+
data: A list containing the input string of ID ranges.
6595
6696
Returns
6797
-------
68-
int: Solution for part 1 of the puzzle
98+
int: The total sum of invalid IDs for Part 1.
6999
"""
70100
check_func = partial(self.has_repeated_sequence, num_repeats=2)
71101
return self.solve_part(data, check_func)
72102

73103
def part2(self, data: list[str]) -> int:
74-
"""Solve the second part of the daily puzzle.
104+
"""Calculate the sum of invalid IDs where a digit sequence is repeated at least twice.
105+
106+
An ID is invalid if it's formed by a sequence of digits repeated two
107+
or more times (e.g., `1212` or `121212`). This method sums all such
108+
IDs found in the input ranges.
75109
76110
Args:
77-
data: List of input strings to be processed
111+
data: A list containing the input string of ID ranges.
78112
79113
Returns
80114
-------
81-
int: Solution for part 2 of the puzzle
115+
int: The total sum of invalid IDs for Part 2.
82116
"""
83117
return self.solve_part(data, self.has_repeated_sequence)

_2025/tests/test_02.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
1-
"""Test suite for Advent of Code daily challenge solution.
1+
"""Test suite for Day 2: Gift Shop
22
3-
This module contains the test cases for the solution to the Advent of Code
4-
daily puzzle. It uses the TestSolutionUtility to run tests for both parts
5-
of the challenge.
3+
This module contains tests for the Day 2 solution, which identifies and sums
4+
invalid product IDs from a list of ranges. The tests verify:
65
7-
The template provides a structure for defining tests for a specific day's
8-
solution, ensuring that the implementation meets the expected outputs for
9-
given test inputs.
6+
1. Part 1: Summing IDs where a digit sequence is repeated exactly twice.
7+
2. Part 2: Summing IDs where a digit sequence is repeated at least twice.
108
"""
119

1210
from aoc.models.tester import TestSolutionUtility
1311

1412

1513
def test_day02_part1() -> None:
16-
"""Test the solution for Part 1 of the daily puzzle.
14+
"""Test summing invalid IDs with a twice-repeated digit sequence.
1715
1816
This test runs the solution for Part 1 of the puzzle against the
1917
provided test input and compares the result with the expected output.
@@ -28,7 +26,7 @@ def test_day02_part1() -> None:
2826

2927

3028
def test_day02_part2() -> None:
31-
"""Test the solution for Part 2 of the daily puzzle.
29+
"""Test summing invalid IDs with a digit sequence repeated at least twice.
3230
3331
This test runs the solution for Part 2 of the puzzle against the
3432
provided test input and compares the result with the expected output.

0 commit comments

Comments
 (0)