wip day3 part2
This commit is contained in:
parent
0aec5c1a70
commit
cbe2b1830d
66
day3/day3.py
66
day3/day3.py
@ -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)
|
||||||
|
numbers.append(Item(start_pos, number))
|
||||||
|
|
||||||
if is_engine_part(neighbors):
|
if is_engine_part(neighbors):
|
||||||
part_number = int("".join(buf))
|
total_parts += int(number)
|
||||||
total_parts += part_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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user