1
0

wip day3 part2

This commit is contained in:
Thibaud Gasser 2023-12-03 23:14:42 +01:00
parent 0aec5c1a70
commit cbe2b1830d

View File

@ -1,11 +1,19 @@
from typing import Tuple, List from typing import Tuple, List, Dict, Set
from dataclasses import dataclass
from collections import defaultdict
@dataclass(frozen=True)
class Item:
pos: Tuple[int, int]
symbol: str
def browse_schema(schema): def browse_schema(schema):
total_parts = 0 total_parts = 0
buf = [] buf = []
max_row, max_col = len(schema), len(schema[0]) max_row, max_col = len(schema), len(schema[0])
numbers: List[Item] = []
for y in range(max_row): for y in range(max_row):
for x in range(max_col): for x in range(max_col):
item = schema[y][x] item = schema[y][x]
@ -14,62 +22,84 @@ def browse_schema(schema):
buf.append(item) buf.append(item)
elif buf: elif buf:
# end of a number, do the engine part check # end of a number, do the engine part check
if buf: number = "".join(buf)
neighbors = get_neighbors((x, y), len(buf), schema) neighbors = get_neighbors((x, y), len(buf), schema)
start_pos = (x-len(number), y)
if is_engine_part(neighbors): numbers.append(Item(start_pos, number))
part_number = int("".join(buf))
total_parts += part_number if is_engine_part(neighbors):
total_parts += int(number)
buf.clear() # reached end of a number, clear buffer
buf.clear() # reached end of a number, clear buffer
print(f"Part 1, sum of the parts numbers = {total_parts}") print(f"Part 1, sum of the parts numbers = {total_parts}")
gears: Dict[Tuple[int, int], Set[Item]] = defaultdict(set)
for y in range(max_row):
for x in range(max_col):
item = schema[y][x]
if item == "*":
print(f"* ({x}, {y})")
neighbors = [n for n in get_neighbors_of((x, y), schema) if n.symbol.isdigit()]
if (x, y) == (5, 8):
breakpoint()
for neighbor in neighbors:
neighboring_numbers = [n for n in numbers
if y-1 <= n.pos[1] == y+1
and n.pos[0] <= neighbor.pos[0] <= n.pos[0] + len(n.symbol)]
gears[(x,y)] = gears[(x,y)].union(neighboring_numbers)
# gears = { key: value for key, value in gears.items() if len(value) <= 2 }
print(f"Part 2, sum of the gear ratios = TODO") print(f"Part 2, sum of the gear ratios = TODO")
def is_engine_part(neighbors: List[str]) -> bool: def is_engine_part(neighbors: List[Item]) -> bool:
# get list of symbols (not '.', \n or a number) # get list of symbols (not '.', \n or a number)
symbols = filter(lambda x: not x.isnumeric() and not x in (".", "\n"), neighbors) symbols = filter(lambda x: not x.symbol.isnumeric() and not x.symbol in (".", "\n"), neighbors)
return next(symbols, None) is not None return next(symbols, None) is not None
def get_neighbors(pos: Tuple[int, int], length: int, schema: List[List[str]]) -> List[str]: def get_neighbors(pos: Tuple[int, int], length: int, schema: List[List[str]]) -> List[Item]:
x, y = pos x, y = pos
start_x = x - length start_x = x - length
neighbors = [get_neighbors_of_digit((x, y), schema) for x in range(start_x, x)] neighbors = [get_neighbors_of((x, y), schema) for x in range(start_x, x)]
neighbors = [item for sublist in neighbors for item in sublist] # flatten list of list neighbors = [item for sublist in neighbors for item in sublist] # flatten list of list
return neighbors return neighbors
def get_neighbors_of_digit(pos: Tuple[int, int], schema: List[List[str]]) -> List[str]: def get_neighbors_of(pos: Tuple[int, int], schema: List[List[str]]) -> List[Item]:
max_row, max_col = len(schema), len(schema[0]) max_row, max_col = len(schema), len(schema[0])
x, y = pos x, y = pos
neighbors = [] neighbors: List[Item] = []
# top # top
if y-1 >= 0: if y-1 >= 0:
neighbors.append(schema[y-1][x]) neighbors.append(Item((x, y-1), schema[y-1][x]))
# bottom: # bottom:
if y+1 < max_row: if y+1 < max_row:
neighbors.append(schema[y+1][x]) neighbors.append(Item((x, y+1), schema[y+1][x]))
# left # left
if x-1 >= 0: if x-1 >= 0:
neighbors.append(schema[y][x-1]) neighbors.append(Item((x-1, y), schema[y][x-1]))
# right # right
if x+1 < max_col: if x+1 < max_col:
neighbors.append(schema[y][x+1]) neighbors.append(Item((x+1, y), schema[y][x+1]))
# top-left # top-left
if y-1 >= 0 and x-1 >= 0: if y-1 >= 0 and x-1 >= 0:
neighbors.append(schema[y-1][x-1]) neighbors.append(Item((x-1, y-1), schema[y-1][x-1]))
# top-right # top-right
if y-1 >= 0 and x+1 < max_col: if y-1 >= 0 and x+1 < max_col:
neighbors.append(schema[y-1][x+1]) neighbors.append(Item((x+1, y-1), schema[y-1][x+1]))
# bottom-left # bottom-left
if y+1 < max_row and x-1 >= 0: if y+1 < max_row and x-1 >= 0:
neighbors.append(schema[y+1][x-1]) neighbors.append(Item((x-1, y+1), schema[y+1][x-1]))
# bottom-right # bottom-right
if y+1 < max_row and x+1 < max_col: if y+1 < max_row and x+1 < max_col:
neighbors.append(schema[y+1][x+1]) neighbors.append(Item((x+1, y+1), schema[y+1][x+1]))
return neighbors return neighbors