#!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)