advent-of-code/2023/python/day03.py

87 lines
2.1 KiB
Python
Raw Normal View History

2023-12-03 21:04:40 +00:00
import matrix
import shared
import itertools
import functools
2023-12-03 21:18:14 +00:00
from pprint import pprint
from collections import defaultdict
2023-12-03 21:04:40 +00:00
SYMBOLS="*%@#+-/$=&"
def get_all_numbers_and_starting_coords(mat):
nums = []
for y, row in enumerate(mat):
x = 0
while x < len(row):
num = matrix.number_starting_at(mat, x,y)
if num is None:
x += 1
continue
nums.append(((x,y), num))
x += len(num)
return nums
def get_row_coords(x1,y, length):
coords = []
for x in range(x1, x1+length):
coords.append((x,y))
return coords
# @shared.profile
def part1(mat):
choose = []
nums = get_all_numbers_and_starting_coords(mat)
for coords, num in nums:
2023-12-03 21:07:42 +00:00
valid, symbol_coord = process_number(mat, coords, num)
2023-12-03 21:04:40 +00:00
if valid:
choose.append(num)
total = 0
for n in choose:
total += int(n)
print(total)
def process_number(mx, coords, num):
line_coords = get_row_coords(*coords, len(num))
for coord in line_coords:
2023-12-03 21:07:42 +00:00
any_symbols = [(cs, v) for cs,v in matrix.get_neighbor_coords(mx, *coord) if v in SYMBOLS]
2023-12-03 21:04:40 +00:00
if any_symbols:
2023-12-03 21:07:42 +00:00
return True, any_symbols[0]
return False, None
2023-12-03 21:04:40 +00:00
# @shared.profile
def part2(mat):
2023-12-03 21:18:14 +00:00
splats = matrix.find_in_matrix(mat, "*", False)
2023-12-03 21:04:40 +00:00
_nums = get_all_numbers_and_starting_coords(mat)
2023-12-03 21:18:14 +00:00
symbols = defaultdict(list)
nums = get_all_numbers_and_starting_coords(mat)
for coords, num in nums:
valid, sc = process_number(mat, coords, num)
if valid:
symbols[(sc[0]['r'],sc[0]['c'])].append(num)
total = 0
for splat in splats:
neighbors = symbols[splat]
if len(neighbors) != 2:
continue
ratio = int(neighbors[0]) * int(neighbors[1])
total += ratio
print(total)
2023-12-03 21:04:40 +00:00
def main():
mat = shared.load_file_char_matrix(shared.get_fname(3))
with shared.elapsed_timer() as elapsed:
part1(mat)
print("🕒", elapsed())
with shared.elapsed_timer() as elapsed:
part2(mat)
print("🕒", elapsed())
if __name__ == "__main__":
main()