Skip to content

Commit 20af921

Browse files
committed
feat: aoc 2025 day 6 solution + tests
1 parent 405e74b commit 20af921

File tree

4 files changed

+141
-0
lines changed

4 files changed

+141
-0
lines changed

_2025/solutions/day06.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
"""Day 6: Trash Compactor
2+
3+
This module provides the solution for Advent of Code 2025 - Day 6.
4+
5+
It evaluates cephalopod math worksheets presented in a compacted, column-wise
6+
format where numbers and operators are aligned vertically across multiple rows.
7+
8+
The module contains a Solution class that inherits from SolutionBase for parsing
9+
and evaluating these rotated math expressions.
10+
"""
11+
12+
import math
13+
14+
from aoc.models.base import SolutionBase
15+
16+
17+
class Solution(SolutionBase):
18+
"""Evaluate cephalopod math worksheets in compacted column format.
19+
20+
This solution processes worksheets where numbers and operators are aligned
21+
vertically in columns. Part 1 evaluates problems by grouping numbers and
22+
operators by column position. Part 2 handles rotated worksheets by parsing
23+
columns in reverse order.
24+
25+
Uses zip transposition to read columns vertically and dynamic expression
26+
evaluation to compute results with both addition and multiplication operators.
27+
"""
28+
29+
def part1(self, data: list[str]) -> int:
30+
"""Evaluate compacted worksheet problems reading columns left-to-right.
31+
32+
Transposes the worksheet rows into columns, where each column represents
33+
either a multi-digit number or an operator (+ or *). Evaluates each
34+
vertical math problem using the operator in the final column.
35+
36+
Args:
37+
data: List of worksheet rows as strings
38+
39+
Returns
40+
-------
41+
int: Sum of all evaluated math problems from the worksheet
42+
"""
43+
cols = list(zip(*[row.strip().split() for row in data]))
44+
score = 0
45+
46+
for group in cols:
47+
nums, operator = group[:-1], group[-1]
48+
score += eval(operator.join(nums))
49+
50+
return score
51+
52+
def part2(self, data: str) -> int:
53+
"""Evaluate rotated worksheet problems reading columns right-to-left.
54+
55+
Parses the worksheet by reversing each row first, then transposing to
56+
read columns from right to left. Identifies blank columns as problem
57+
separators and evaluates expressions where '*' means multiplication
58+
and '+' means addition of all numbers in the problem.
59+
60+
Args:
61+
data: Raw worksheet input as a single string
62+
63+
Returns
64+
-------
65+
int: Sum of all evaluated rotated math problems
66+
"""
67+
lines = data.rstrip("\n").splitlines()
68+
69+
max_width = max(len(line) for line in lines)
70+
lines = [line.ljust(max_width) for line in lines]
71+
72+
operators = []
73+
problems = []
74+
current_problem = []
75+
76+
for col in zip(*[line[::-1] for line in lines]):
77+
if all(char == " " for char in col):
78+
continue
79+
80+
digit_chars = [char for char in col[:-1] if char != " "]
81+
has_digits = bool(digit_chars)
82+
83+
if has_digits:
84+
current_problem.append(int("".join(digit_chars)))
85+
86+
if col[-1] != " ":
87+
operators.append(col[-1])
88+
problems.append(current_problem)
89+
current_problem = []
90+
91+
return sum([
92+
(math.prod(problem) if operator == "*" else sum(problem))
93+
for operator, problem in zip(operators, problems)
94+
])
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
123 328 51 64
2+
45 64 387 23
3+
6 98 215 314
4+
* + * +
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
123 328 51 64
2+
45 64 387 23
3+
6 98 215 314
4+
* + * +

_2025/tests/test_06.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"""Day 6: Trash Compactor
2+
3+
This module contains tests for the Day 6 solution, which evaluates cephalopod
4+
math worksheets laid out in a compacted, column-wise format. The tests verify:
5+
6+
1. Part 1: Evaluating each vertically aligned problem using the given operator
7+
2. Part 2: Evaluating rotated worksheet problems with column-based parsing
8+
"""
9+
from aoc.models.tester import TestSolutionUtility
10+
11+
12+
def test_day06_part1() -> None:
13+
"""Test evaluating compacted worksheet problems as given.
14+
15+
This test runs the solution for Part 1 of the puzzle against the
16+
provided test input and compares the result with the expected output.
17+
"""
18+
TestSolutionUtility.run_test(
19+
year=2025,
20+
day=6,
21+
is_raw=False,
22+
part_num=1,
23+
expected=4277556,
24+
)
25+
26+
27+
def test_day06_part2() -> None:
28+
"""Test evaluating rotated worksheet problems parsed column-wise.
29+
30+
This test runs the solution for Part 2 of the puzzle against the
31+
provided test input and compares the result with the expected output.
32+
"""
33+
TestSolutionUtility.run_test(
34+
year=2025,
35+
day=6,
36+
is_raw=True,
37+
part_num=2,
38+
expected=3263827,
39+
)

0 commit comments

Comments
 (0)