1
0

update day 3 (still wip)

This commit is contained in:
Thibaud Gasser 2023-12-04 15:31:06 +01:00
parent 619b2dd456
commit 88e2e2fdf7

View File

@ -1,17 +1,18 @@
from typing import Tuple, List, Dict, Set from typing import Tuple, List, Set
from dataclasses import dataclass from dataclasses import dataclass
from collections import defaultdict
@dataclass(frozen=True) @dataclass(frozen=True)
class Item: class Item:
pos: Tuple[int, int] pos: Tuple[int, int]
symbol: str 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])
symbols: List[Tuple[Item, Set[Item]]] = []
numbers: List[Item] = [] numbers: List[Item] = []
for y in range(max_row): for y in range(max_row):
@ -20,11 +21,15 @@ def browse_schema(schema):
if item.isnumeric(): if item.isnumeric():
# continue parsing full number # continue parsing full number
buf.append(item) buf.append(item)
elif buf: else:
neighbors = get_neighbors_of((x, y), schema)
symbols.append((Item((x, y), item), set(neighbors)))
if buf and not item.isnumeric():
# end of a number, do the engine part check # end of a number, do the engine part check
number = "".join(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) start_pos = (x-len(number), y)
symbols.append((Item((x, y), number), get_neighbors_of((x, y), schema)))
numbers.append(Item(start_pos, number)) numbers.append(Item(start_pos, number))
if is_engine_part(neighbors): if is_engine_part(neighbors):
@ -33,28 +38,27 @@ def browse_schema(schema):
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}")
part2(symbols, numbers)
gears: Dict[Tuple[int, int], Set[Item]] = defaultdict(set) def part2(symbols, numbers):
for y in range(max_row): total_gears = 0
for x in range(max_col): stars = [(s, neighbors) for s, neighbors in symbols if s.symbol == "*"]
item = schema[y][x] for _, neighbors in stars:
if item == "*": corresponding_numbers = set()
print(f"* ({x}, {y})") digits = [n for n in neighbors if n.symbol.isdigit()]
neighbors = [n for n in get_neighbors_of((x, y), schema) if n.symbol.isdigit()] for digit in digits:
if (x, y) == (5, 8): # find full number (number.start_pos < digit.pos < number.end_pos)
breakpoint() for number in numbers:
if number.pos[1] - 1 <= digit.pos[1] <= number.pos[1] + 1 and number.pos[0] <= digit.pos[0] <= number.pos[0]+len(number.symbol):
corresponding_numbers.add(number.symbol)
for neighbor in neighbors: if len(corresponding_numbers) == 2:
neighboring_numbers = [n for n in numbers a, b = corresponding_numbers
if y-1 <= n.pos[1] == y+1 total_gears += int(a) * int(b)
and n.pos[0] <= neighbor.pos[0] <= n.pos[0] + len(n.symbol)] #print(f"star: {star.pos} {corresponding_numbers}")
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 gear ratios = {total_gears}")
print(f"Part 2, sum of the gear ratios = TODO")
def is_engine_part(neighbors: List[Item]) -> bool: def is_engine_part(neighbors: List[Item]) -> bool: