1+ """Day 2: Cube Conundrum.
2+
3+ This module provides the solution for Advent of Code 2023 - Day 2.
4+ It handles analysis of cube games where colored cubes are drawn from a bag
5+ in multiple sets, with each game having several draws of red, green, and blue cubes.
6+
7+ The module contains a Solution class that inherits from SolutionBase and implements
8+ methods to validate games against thresholds and find minimum required cubes.
9+ """
10+
111from math import prod
212import re
313
414from aoc .models .base import SolutionBase
515
616
717class Solution (SolutionBase ):
8- """Solution for Advent of Code 2023 - Day 2: Cube Conundrum .
18+ """Analyse cube games for validity and minimum requirements .
919
10- This class solves a puzzle involving a game where colored cubes are drawn from
11- a bag in multiple sets. Each game consists of several draws, and each draw
12- reveals a certain number of red, green, and blue cubes.
13-
14- Input format:
15- List of strings where each line represents a game in the format:
16- "Game N: X red, Y green, Z blue; A red, B green, C blue; ..."
20+ This solution processes games where colored cubes are drawn from a bag.
21+ Part 1 validates games against thresholds for each color.
22+ Part 2 calculates the minimum number of cubes required for each game.
1723
1824 The solution uses regex patterns to extract game IDs and cube counts,
1925 validating them against thresholds (Part 1) and finding minimum required
@@ -27,71 +33,56 @@ class Solution(SolutionBase):
2733 def is_possible (self , data : str ) -> bool :
2834 """Check if a set of cube draws is possible given the thresholds.
2935
30- Examines each color count in the draw and verifies it doesn't
31- exceed the predefined thresholds (12 red, 13 green, 14 blue).
32-
3336 Args:
34- data: String containing cube counts for a single set
35- Example: "3 blue, 4 red"
37+ data (str): String containing cube counts for a single set
3638
3739 Returns
3840 -------
3941 Boolean indicating whether the draw is possible with given thresholds
4042 """
41- # Check if all extracted counts are within the thresholds
4243 for count , color in re .findall (self .color_regex , data ):
4344 if int (count ) > self .thresholds [color ]:
44- return False # Violates threshold
45+ return False
4546
4647 return True
4748
4849 def part1 (self , data : list [str ]) -> int :
4950 """Sum IDs of games possible with the given cube thresholds.
5051
51- Processes each game to determine if all its sets are possible
52- given the cube limits (12 red, 13 green, 14 blue). For valid
53- games, adds their ID to the running sum.
54-
5552 Args:
56- data: List of strings containing game configurations
53+ data (list[str]) : List of game strings in format "Game N: X red, Y green, Z blue; ..."
5754
5855 Returns
5956 -------
60- Sum of IDs of all possible games
57+ Sum of IDs for games where all draws are within thresholds
6158 """
62- count = 0
59+ total = 0
6360 for game in data :
64- game_id , sets = game . split ( ":" )[ 0 ] , game . split ( ":" )[ - 1 ]. strip (). split ( ";" )
65- game_id = int ( re . search ( self . id_regex , game_id ). group ( 1 ) )
66- if all ([ self .is_possible (cubes ) for cubes in sets ] ):
67- count += game_id
61+ game_id = int ( re . search ( self . id_regex , game ). group ( 1 ) )
62+ sets = game . split ( ":" )[ 1 ]. split ( ";" )
63+ if all (self .is_possible (s ) for s in sets ):
64+ total += game_id
6865
69- return count
66+ return total
7067
7168 def part2 (self , data : list [str ]) -> int :
72- """Calculate sum of power of minimum cube sets needed for each game.
73-
74- For each game, determines the minimum number of cubes of each color
75- that would be needed to make the game possible. The power of a set
76- is the product of the minimum required numbers of red, green, and
77- blue cubes.
69+ """Calculate the sum of minimum cube powers for each game.
7870
7971 Args:
80- data: List of strings containing game configurations
72+ data (list[str]) : List of game strings in format "Game N: X red, Y green, Z blue; ..."
8173
8274 Returns
8375 -------
84- Sum of the power of minimum required cube sets across all games
76+ Sum of the product of minimum required cubes for each color in each game
8577 """
8678 total = 0
87- for row in data :
88- cubes = {"red" : 0 , "green" : 0 , "blue" : 0 }
89- game = row .split (":" )[- 1 ].strip ()
90-
91- for count , color in re .findall (self .color_regex , game ):
92- if int (count ) > cubes [color ]:
93- cubes [color ] = int (count )
79+ for game in data :
80+ sets = game .split (":" )[1 ].split (";" )
81+ min_cubes = {"red" : 0 , "green" : 0 , "blue" : 0 }
82+ for s in sets :
83+ for count , color in re .findall (self .color_regex , s ):
84+ min_cubes [color ] = max (min_cubes [color ], int (count ))
9485
95- total += prod (cubes .values ())
86+ total += prod (min_cubes .values ())
9687
9788 return total
0 commit comments