update day 3 (still wip)
This commit is contained in:
parent
619b2dd456
commit
88e2e2fdf7
46
day3/day3.py
46
day3/day3.py
@ -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,30 +38,29 @@ 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:
|
||||||
# get list of symbols (not '.', \n or a number)
|
# get list of symbols (not '.', \n or a number)
|
||||||
symbols = filter(lambda x: not x.symbol.isnumeric() and not x.symbol in (".", "\n"), neighbors)
|
symbols = filter(lambda x: not x.symbol.isnumeric() and not x.symbol in (".", "\n"), neighbors)
|
||||||
|
Loading…
Reference in New Issue
Block a user