Skip to content

Commit 08cf700

Browse files
committed
Day 11 solution
1 parent a678fa3 commit 08cf700

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

solutions/day11.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
from collections import Counter
2+
from typing import List
3+
4+
from aoc.models.base import SolutionBase
5+
6+
7+
class Solution(SolutionBase):
8+
"""Solution for Advent of Code 2024 - Day 11: Plutonian Pebbles.
9+
10+
This class solves a puzzle involving transforming sequences of numbers (stones)
11+
according to specific rules over multiple iterations (blinks). Each stone undergoes
12+
one of three transformations based on its characteristics: conversion to 1 if it's
13+
a single zero, splitting in half if even-length, or multiplication by 2024 if odd-length.
14+
15+
Input format:
16+
List containing a single string of space-separated numbers representing the initial
17+
stone values. Each value is a non-negative integer represented as a string.
18+
19+
This class inherits from `SolutionBase` and provides methods to process stone
20+
transformations and calculate the total number of stones after a specified number
21+
of iterations.
22+
"""
23+
24+
def split_stones(self, stones_data: str, total_blinks: int) -> int:
25+
"""Process stones through multiple iterations of transformations.
26+
27+
Each stone undergoes one of three transformations in each blink:
28+
1. If stone is "0", it becomes "1"
29+
2. If stone length is even, split into two equal parts (removing leading zeros)
30+
3. If stone length is odd, multiply by 2024
31+
32+
Args:
33+
stones_data (str): Space-separated string of initial stone values
34+
total_blinks (int): Number of transformation iterations to perform
35+
36+
Returns:
37+
int: Total number of stones after all transformations are complete
38+
"""
39+
stones = Counter(stones_data.split())
40+
blinks = 1
41+
42+
while blinks <= total_blinks:
43+
new_stones = Counter()
44+
for stone, count in stones.items():
45+
if len(stone) == 1 and stone == "0":
46+
new_stones["1"] += count
47+
48+
elif len(stone) % 2 == 0:
49+
midpoint = len(stone) // 2
50+
left = str(int(stone[:midpoint])) if stone[:midpoint] else "0"
51+
right = str(int(stone[midpoint:])) if stone[midpoint:] else "0"
52+
53+
new_stones[left] += count
54+
new_stones[right] += count
55+
56+
else:
57+
new_stones[str(int(stone) * 2024)] += count
58+
59+
stones = new_stones
60+
blinks += 1
61+
62+
return sum(stones.values())
63+
64+
def part1(self, data: List[str]) -> int:
65+
"""Calculate total stones after 25 blinks of transformations.
66+
67+
Args:
68+
data (List[str]): Input lines containing the initial stone values
69+
70+
Returns:
71+
int: Total number of stones after 25 transformation iterations
72+
"""
73+
return self.split_stones(data[0], 25)
74+
75+
def part2(self, data: List[str]) -> int:
76+
"""Calculate total stones after 75 blinks of transformations.
77+
78+
Args:
79+
data (List[str]): Input lines containing the initial stone values
80+
81+
Returns:
82+
int: Total number of stones after 75 transformation iterations
83+
"""
84+
return self.split_stones(data[0], 75)

tests/data/day11/test_01_input.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
125 17

tests/test_11.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from aoc.models.tester import TestSolutionUtility
2+
3+
4+
def test_day11_part1():
5+
TestSolutionUtility.run_test(
6+
day=11,
7+
is_raw=False,
8+
part_num=1,
9+
expected=55312,
10+
)

0 commit comments

Comments
 (0)