Cleaned up a bit
Switched to using classes instead of objs
This commit is contained in:
parent
08fc9693b6
commit
d5e3d9eb58
|
|
@ -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)}");
|
||||||
Loading…
Reference in New Issue