You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
3.2 KiB
139 lines
3.2 KiB
10 months ago
|
#!python3
|
||
|
|
||
|
|
||
|
|
||
|
import argparse
|
||
|
parser = argparse.ArgumentParser()
|
||
|
parser.add_argument("filename", help="the file from which to take the list of games")
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
parts = []
|
||
|
notparts = []
|
||
|
gearsum = 0
|
||
|
|
||
|
|
||
|
def check_neighbors(nbrs):
|
||
|
for n in nbrs:
|
||
|
if n not in ".0123456789\n":
|
||
|
return True
|
||
|
|
||
|
def neighbors(x, y, ls):
|
||
|
out = []
|
||
|
for dx in range(-1,2):
|
||
|
for dy in range(-1,2):
|
||
|
if dx == 0 and dy == 0:
|
||
|
continue
|
||
|
if y+dy < 0 or y+dy >= len(ls):
|
||
|
continue
|
||
|
if x+dx < 0 or x+dx >= len(ls[y+dy]):
|
||
|
continue
|
||
|
out.append(ls[y+dy][x+dx])
|
||
|
return out
|
||
|
|
||
|
def numerical_neighbors(x, y, ls):
|
||
|
out = set()
|
||
|
for dx in range(-1, 2):
|
||
|
for dy in range(-1, 2):
|
||
|
if dx == 0 and dy == 0:
|
||
|
continue
|
||
|
if y+dy < 0 or y+dy >= len(ls):
|
||
|
continue
|
||
|
if x+dx < 0 or x+dx >= len(ls[y+dy]):
|
||
|
continue
|
||
|
|
||
|
|
||
|
if ls[y+dy][x+dx] in "0123456789":
|
||
|
out |= {(x+dx,y+dy, ls[y+dy][x+dx])}
|
||
|
|
||
|
return out
|
||
|
|
||
|
def get_number(x,y, lines):
|
||
|
"""assumes (x,y) is the coordinates of a digit in lines"""
|
||
|
while x-1 >= 0 and lines[y][x-1] in "0123456789":
|
||
|
x = x-1
|
||
|
start = (x,y)
|
||
|
|
||
|
number = ""
|
||
|
coords = set()
|
||
|
while lines[y][x] in "0123456789":
|
||
|
number += lines[y][x]
|
||
|
coords |= {(x,y)}
|
||
|
x += 1
|
||
|
if x >= len(lines[y]): break
|
||
|
|
||
|
return (number, frozenset(coords))
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
with open(args.filename, "r") as file:
|
||
|
lines = file.readlines()
|
||
|
for y, l in enumerate(lines):
|
||
|
number = ""
|
||
|
nbrs = []
|
||
|
for x, c in enumerate(l):
|
||
|
if c == "\n": print("HEYYYY")
|
||
|
if c in "0123456789":
|
||
|
number = number + c
|
||
|
nbrs.extend(neighbors(x,y,lines))
|
||
|
if c not in "0123456789\n" and number != "":
|
||
|
if check_neighbors(nbrs):
|
||
|
#print("found a number:", number, "".join(nbrs), " and accepted it")
|
||
|
parts.append(int(number))
|
||
|
else:
|
||
|
#print("found a number:", number, "".join(nbrs), " and rejected it")
|
||
|
notparts.append(int(number))
|
||
|
number = ""
|
||
|
nbrs = []
|
||
|
if c not in "0123456789":
|
||
|
continue
|
||
|
if number != "":
|
||
|
if check_neighbors(nbrs):
|
||
|
print("found a number:", number, "".join(nbrs), " and accepted it")
|
||
|
parts.append(int(number))
|
||
|
else:
|
||
|
print("found a number:", number, "".join(nbrs), " and rejected it")
|
||
|
notparts.append(int(number))
|
||
|
number = ""
|
||
|
nbrs = []
|
||
|
|
||
|
|
||
|
gearsum = 0
|
||
|
for y, l in enumerate(lines):
|
||
|
for x, c in enumerate(l):
|
||
|
if c == "*":
|
||
|
print("found a gear at ", x, " ", y)
|
||
|
gear_nums = []
|
||
|
gear_coordsets = set()
|
||
|
# we found a gear
|
||
|
neighbors = numerical_neighbors(x,y,lines)
|
||
|
print("the gear had neighbors ", neighbors)
|
||
|
for xa, ya, neighboring_number in neighbors:
|
||
|
number, coords = get_number(xa, ya, lines)
|
||
|
print("found a neighbor ", number, " at coords ", coords)
|
||
|
if coords in gear_coordsets:
|
||
|
print("rejecting that neighbor because we already got it")
|
||
|
# we've already got this number. mvoe alnog
|
||
|
continue
|
||
|
else:
|
||
|
print("adding it to gear cordsets", gear_coordsets)
|
||
|
gear_nums.append(number)
|
||
|
gear_coordsets |= {coords}
|
||
|
print("which corresponded to numbers", gear_nums)
|
||
|
|
||
|
if len(gear_nums) == 2:
|
||
|
gearsum += int(gear_nums[0])*int(gear_nums[1])
|
||
|
|
||
|
|
||
|
|
||
|
print("accepted:")
|
||
|
print(parts)
|
||
|
print("rejected:")
|
||
|
print(notparts)
|
||
|
|
||
|
print("sum of parts are:", sum(parts))
|
||
|
print("sum of unique parts are: ", sum(set(parts)))
|
||
|
print("gear sum is: ", gearsum)
|
||
|
|
||
|
|