diff --git a/day-03/src/part02.py b/day-03/src/part02.py index ea0040d..06dd2bb 100644 --- a/day-03/src/part02.py +++ b/day-03/src/part02.py @@ -1,7 +1,6 @@ import sys import copy -import string -from dataclasses import dataclass +from dataclasses import dataclass, field DEBUG = True padding=40 @@ -23,177 +22,144 @@ parts = []; part_numbers = []; - -def hasNumber(part): - window = \ - [[[-1,-1],[0,-1],[1,-1]], - [[-1, 0],[0, 0],[1, 0]], - [[-1, 1],[0, 1],[1, 1]]] - for w_y in window: - for transform in w_y: - has_no=False - transformed_x = part['x'] + transform[0] - transformed_y = part['y'] + transform[1] - debug_print("hasNumber::check_location", f"part==[{part['x']}, {part['y']}]; engine[{transformed_x}, {transformed_y}] == {engine[transformed_y][transformed_x]}") - if engine[transformed_y][transformed_x].isdigit(): - part['has_number'] = True - #if engine[part.w_x][] - #debug_print("aaaaa not matricies", f"part=[{part['x']},{part['y']}] x:", engine) - pass +@dataclass +class P: + x: int = 0 + y: int = 0 -def numberIsPartOfPart(part_number): - window = \ - [[[-1,-1],[0,-1],[1,-1]], - [[-1, 0],[0, 0],[1, 0]], - [[-1, 1],[0, 1],[1, 1]]] - - for digit in part_number['locations']: - for w_y in window: - for transform in w_y: - transformed_x = digit['x'] + transform[0] - transformed_y = digit['y'] + transform[1] - if transformed_y < 0 or transformed_y >= len(engine): - continue - if transformed_x < 0 or transformed_x >= len(engine[transformed_y]): - continue - debug_print("numberIsPartOfPart", f"letter {digit['digit']} point [{transformed_x}, {transformed_y}] is a valid coord. contains: {engine[transformed_y][transformed_x]}") - if engine[transformed_y][transformed_x] != '.' and not engine[transformed_y][transformed_x].isdigit(): - debug_print("numberIsPartOfPart", f"Number is part of part") - part_number['is_part_of_part'] = True - for part in parts: - if part['x'] != transformed_x or part['y'] != transformed_y: - continue - part['attached_numbers'].add(part_number['integer']) - pass - pass - pass - - - - -debug_print("Parse Input") -#========INPUT PARSE========== +print("Parsing Input:") +print("") +print("===================================\n"); #for line in sys.stdin: for line in f.readlines(): line = line.strip() - debug_print("input", line) + #debug_print("input", line) engine.append(line) debug_print("engine") # https://stackoverflow.com/questions/17870612/printing-a-two-dimensional-array-in-python print('\n'.join([''.join(['{:1}'.format(item) for item in row]) for row in engine])) -#============================= +print("") +print("Proccessing:") +print("") +print("===================================\n"); + #=====Extract Parts===== debug_print("Extract Parts") -empty_part = { - 'x': 0, - 'y': 0, - 'symbol': '', - 'attached_numbers': set() -} +@dataclass +class Part: + x: int = 0 + y: int = 0 + symbol: str = '' + attached_numbers: set = field(default_factory=set) -debug_print("Extract Parts") for y in range(len(engine)): for x in range(len(engine[y])): #debug_print("slot ",f"x:{x}, y:{y}", engine[y][x]) if engine[y][x] == '.' or engine[y][x].isdigit(): continue - temp_part = copy.deepcopy(empty_part) - temp_part['x'] = x - temp_part['y'] = y - temp_part['symbol'] = engine[y][x] - parts.append(temp_part) - debug_print("Found Part", f"{parts[-1]}") - #hasNumber(parts[-1]) - + parts.append(Part(x, y, engine[y][x])) + #debug_print("Found Part", f"{parts[-1]}") +debug_print("Extract Parts", f"Found {len(parts)} parts") #============================== #=====Extract Part Numbers===== debug_print("Extract Part Numbers") -empty_partno = { - 'is_part_of_part': False, - 'ascii': "", - 'gen_int': False, - 'integer': 0, - 'locations': [] -} -current_parsing_part_number = copy.deepcopy(empty_partno) +@dataclass +class PartNumber: + ascii: str = "" + locations: list = field(default_factory=list) + is_part_of_part = False + def number(self): + return int(self.ascii) + + +current_parsing_part_number = PartNumber() for y in range(len(engine)): for x in range(len(engine[y])): if engine[y][x].isdigit(): - current_parsing_part_number['ascii'] += engine[y][x] - current_parsing_part_number['locations'].append({'digit':engine[y][x], 'x':x, 'y':y}) + current_parsing_part_number.ascii += engine[y][x] + current_parsing_part_number.locations.append(P(x,y)) else: - if current_parsing_part_number['ascii'] == "": + if current_parsing_part_number.ascii == "": continue - debug_print("PARTNOEXT", f"found complete part number: {current_parsing_part_number['ascii'].rjust(4)}, locations: {current_parsing_part_number['locations']}") - current_parsing_part_number['integer'] = int(current_parsing_part_number['ascii']) - current_parsing_part_number['gen_int'] = True + #debug_print("PARTNOEXT", f"found complete part number: {current_parsing_part_number['ascii'].rjust(4)}, locations: {current_parsing_part_number['locations']}") part_numbers.append(current_parsing_part_number) - current_parsing_part_number = copy.deepcopy(empty_partno) - numberIsPartOfPart(part_numbers[-1]) + current_parsing_part_number = PartNumber() pass pass - +debug_print("Extract Part Numbers", f"Found {len(part_numbers)} part numbers") #============================== -for part in parts: - debug_print("parts print", part) +#mutates part_numbers and parts +def linkPartNumbersToParts(engine, part_numbers, parts): + window = \ + [[[-1,-1],[0,-1],[1,-1]], + [[-1, 0],[0, 0],[1, 0]], + [[-1, 1],[0, 1],[1, 1]]] + + for part_number in part_numbers: + for digit in part_number.locations: + for w_y in window: + for transform in w_y: + transformed_x = digit.x + transform[0] + transformed_y = digit.y + transform[1] + if transformed_y < 0 or transformed_y >= len(engine): + continue + if transformed_x < 0 or transformed_x >= len(engine[transformed_y]): + continue + debug_print("linkPartNumbersToParts", f"letter {digit} point [{transformed_x}, {transformed_y}] is a valid coord. contains: {engine[transformed_y][transformed_x]}") + if engine[transformed_y][transformed_x] != '.' and not engine[transformed_y][transformed_x].isdigit(): + debug_print("numberIsPartOfPart", f"Number is part of part") + part_number.is_part_of_part= True + for part in parts: + if part.x != transformed_x or part.y != transformed_y: + continue + part.attached_numbers.add(part_number.number()) - -for part_number in part_numbers: - debug_print("part_number print", part_number) - - -gears = [] - -for part in parts: - if part['symbol'] != '*' or len(part['attached_numbers']) != 2: - continue - debug_print("gear", part) - debug_print("gear len attached", len(part['attached_numbers'])) - gears.append(part['attached_numbers']) - - -debug_print("gears list: ", gears) +linkPartNumbersToParts(engine, part_numbers, parts) +#for part_number in part_numbers: +# debug_print("part_number print", part_number) - -# Insert Processing Code - - - - - - -parts_that_are_attached_to_parts = [part_number['integer'] for part_number in part_numbers if part_number['is_part_of_part'] == True] -debug_print("parts_that_are_attached_to_parts", parts_that_are_attached_to_parts) - - -gear_ratios = [pn.pop()*pn.pop() for pn in gears] -debug_print("gear_ratios", gear_ratios) - +#for part in parts: +# debug_print("parts print", part) print("") -print("Processed:") +print("Calculating Answer:") print("") print("===================================\n"); -print("parts_that_are_attached_to_parts") -print(f"Answer: \n{sum(parts_that_are_attached_to_parts)}"); -print("sum of gear_ratios") + +part_numbers_that_are_attached_to_parts = [part_number.number() for part_number in part_numbers if part_number.is_part_of_part == True] +debug_print("Attached Parts", f"Found {len(part_numbers_that_are_attached_to_parts)} part numbers that are attached to a part") + +gears = [part.attached_numbers for part in parts if part.symbol == '*' and len(part.attached_numbers) == 2] +debug_print("Find Gears", f"Found {len(gears)} gears") +gear_ratios = [pn.pop()*pn.pop() for pn in gears] + +#for part in parts: +# debug_print("parts print", part) +# part.getAttachedNumbers(part_numbers) + +print("") + +print("===================================\n"); +print("sum of part numbers that are attached to parts") +print(f"Answer: \n{sum(part_numbers_that_are_attached_to_parts)}"); +print("sum of gear ratios") print(f"Answer: \n{sum(gear_ratios)}"); \ No newline at end of file