Cleaned up a bit

Switched to using classes instead of objs
This commit is contained in:
icaema 2023-12-03 15:56:30 -05:00
parent 08fc9693b6
commit d5e3d9eb58
1 changed files with 88 additions and 122 deletions

View File

@ -1,7 +1,6 @@
import sys import sys
import copy import copy
import string from dataclasses import dataclass, field
from dataclasses import dataclass
DEBUG = True DEBUG = True
padding=40 padding=40
@ -23,177 +22,144 @@ parts = [];
part_numbers = []; part_numbers = [];
@dataclass
def hasNumber(part): class P:
window = \ x: int = 0
[[[-1,-1],[0,-1],[1,-1]], y: int = 0
[[-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
def numberIsPartOfPart(part_number): print("Parsing Input:")
window = \ print("")
[[[-1,-1],[0,-1],[1,-1]], print("===================================\n");
[[-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==========
#for line in sys.stdin: #for line in sys.stdin:
for line in f.readlines(): for line in f.readlines():
line = line.strip() line = line.strip()
debug_print("input", line) #debug_print("input", line)
engine.append(line) engine.append(line)
debug_print("engine") debug_print("engine")
# https://stackoverflow.com/questions/17870612/printing-a-two-dimensional-array-in-python # https://stackoverflow.com/questions/17870612/printing-a-two-dimensional-array-in-python
print('\n'.join([''.join(['{:1}'.format(item) for item in row]) print('\n'.join([''.join(['{:1}'.format(item) for item in row])
for row in engine])) for row in engine]))
#=============================
print("")
print("Proccessing:")
print("")
print("===================================\n");
#=====Extract Parts===== #=====Extract Parts=====
debug_print("Extract Parts") debug_print("Extract Parts")
empty_part = { @dataclass
'x': 0, class Part:
'y': 0, x: int = 0
'symbol': '', y: int = 0
'attached_numbers': set() symbol: str = ''
} attached_numbers: set = field(default_factory=set)
debug_print("Extract Parts")
for y in range(len(engine)): for y in range(len(engine)):
for x in range(len(engine[y])): for x in range(len(engine[y])):
#debug_print("slot ",f"x:{x}, y:{y}", engine[y][x]) #debug_print("slot ",f"x:{x}, y:{y}", engine[y][x])
if engine[y][x] == '.' or engine[y][x].isdigit(): if engine[y][x] == '.' or engine[y][x].isdigit():
continue continue
temp_part = copy.deepcopy(empty_part) parts.append(Part(x, y, engine[y][x]))
temp_part['x'] = x #debug_print("Found Part", f"{parts[-1]}")
temp_part['y'] = y debug_print("Extract Parts", f"Found {len(parts)} parts")
temp_part['symbol'] = engine[y][x]
parts.append(temp_part)
debug_print("Found Part", f"{parts[-1]}")
#hasNumber(parts[-1])
#============================== #==============================
#=====Extract Part Numbers===== #=====Extract Part Numbers=====
debug_print("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 y in range(len(engine)):
for x in range(len(engine[y])): for x in range(len(engine[y])):
if engine[y][x].isdigit(): if engine[y][x].isdigit():
current_parsing_part_number['ascii'] += engine[y][x] 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.locations.append(P(x,y))
else: else:
if current_parsing_part_number['ascii'] == "": if current_parsing_part_number.ascii == "":
continue continue
debug_print("PARTNOEXT", f"found complete part number: {current_parsing_part_number['ascii'].rjust(4)}, locations: {current_parsing_part_number['locations']}") #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
part_numbers.append(current_parsing_part_number) part_numbers.append(current_parsing_part_number)
current_parsing_part_number = copy.deepcopy(empty_partno) current_parsing_part_number = PartNumber()
numberIsPartOfPart(part_numbers[-1])
pass pass
pass pass
debug_print("Extract Part Numbers", f"Found {len(part_numbers)} part numbers")
#============================== #==============================
for part in parts: #mutates part_numbers and parts
debug_print("parts print", part) 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())
linkPartNumbersToParts(engine, part_numbers, parts)
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)
#for part_number in part_numbers:
# debug_print("part_number print", part_number)
#for part in parts:
# Insert Processing Code # debug_print("parts print", part)
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)
print("") print("")
print("Processed:") print("Calculating Answer:")
print("") print("")
print("===================================\n"); print("===================================\n");
print("parts_that_are_attached_to_parts")
print(f"Answer: \n{sum(parts_that_are_attached_to_parts)}"); part_numbers_that_are_attached_to_parts = [part_number.number() for part_number in part_numbers if part_number.is_part_of_part == True]
print("sum of gear_ratios") 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)}"); print(f"Answer: \n{sum(gear_ratios)}");