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.

99 lines
3.1 KiB

lines = open('inputs/day3.txt').readlines()
xlen = len(lines)
ylen = len(lines[0])
def symbol_positions(lines: list[str]) -> list[tuple]:
positions = []
symbols = []
for idx, line in enumerate(lines):
for idy, c in enumerate(line.strip('\n')):
if not c.isdigit() and c != ".":
positions.append((idx, idy))
symbols.append(c)
return positions, symbols
def find_first_digit(lines: list[str], coords: tuple) -> tuple:
x, y = coords
if y == 0:
return coords
elif not lines[x][y-1].isdigit():
return coords
else:
return find_first_digit(lines, (x, y-1))
def full_number(lines: list[str], coords: tuple) -> int:
x, y = coords
nr = lines[x][y]
counter = 1
while (y + counter) < (ylen - 1):
if lines[x][y + counter].isdigit():
nr += lines[x][y + counter]
counter += 1
else:
break
return int(nr)
def adjacent_numbers(lines: list[str], xy: tuple) -> tuple:
# returns bool and coords of first digit in number
coords = []
x, y = xy
neighbours_exist = False
if x > 0:
if lines[x-1][y].isdigit():
neighbours_exist = True
coords.append(find_first_digit(lines, (x-1, y)))
if y > 0:
if lines[x-1][y-1].isdigit():
neighbours_exist = True
coords.append(find_first_digit(lines, (x-1, y-1)))
if y < (ylen - 1):
if lines[x-1][y+1].isdigit():
neighbours_exist = True
coords.append(find_first_digit(lines, (x-1, y+1)))
if x < (xlen - 1):
if lines[x+1][y].isdigit():
neighbours_exist = True
coords.append(find_first_digit(lines, (x+1, y)))
if y > 0:
if lines[x+1][y-1].isdigit():
neighbours_exist = True
coords.append(find_first_digit(lines, (x+1, y-1)))
if y < (ylen - 1):
if lines[x+1][y+1].isdigit():
neighbours_exist = True
coords.append(find_first_digit(lines, (x+1, y+1)))
if y > 0:
if lines[x][y-1].isdigit():
neighbours_exist = True
coords.append(find_first_digit(lines, (x, y-1)))
if y < (ylen - 1):
if lines[x][y+1].isdigit():
neighbours_exist = True
coords.append(find_first_digit(lines, (x, y+1)))
return neighbours_exist, set(coords)
positions, symbols = symbol_positions(lines)
numbers_pos = []
for s in positions:
has_neighbour, coords = adjacent_numbers(lines, s)
if has_neighbour:
numbers_pos.append(coords)
number_coords = set([x for y in numbers_pos for x in y])
numbers = []
for nr in number_coords:
numbers.append(full_number(lines, nr))
print(f'Solution Part 1: {sum(numbers)}')
gear_ratios = []
for p, c in zip(positions, symbols):
if c == "*":
has_neighbour, coords = adjacent_numbers(lines, p)
coords = list(coords)
if len(coords) == 2:
gear_ratios.append(full_number(lines, coords[0]) * full_number(lines, coords[1]))
print(f"Solution Part 2: {sum(gear_ratios)}")