Improve lib and use it to solve 3 and 17.
This commit is contained in:
48
lib.py
48
lib.py
@@ -7,16 +7,6 @@ NUMBERS = string.digits
|
||||
LETTERS_LOWER = string.ascii_lowercase
|
||||
LETTERS_UPPER = string.ascii_uppercase
|
||||
|
||||
UP = (-1, 0)
|
||||
DOWN = (1, 0)
|
||||
RIGHT = (0, 1)
|
||||
LEFT = (0, -1)
|
||||
|
||||
NORTH = UP
|
||||
SOUTH = DOWN
|
||||
EAST = RIGHT
|
||||
WEST = LEFT
|
||||
|
||||
INF = float("inf")
|
||||
fst = lambda l: l[0]
|
||||
snd = lambda l: l[1]
|
||||
@@ -33,6 +23,15 @@ def add2(a: tuple[int, int], b: tuple[int, int]) -> tuple[int, int]:
|
||||
return (a[0] + b[0], a[1] + b[1])
|
||||
|
||||
class Grid2D:
|
||||
N = (-1, 0)
|
||||
E = (0, 1)
|
||||
S = (1, 0)
|
||||
W = (0, -1)
|
||||
NW = (-1, -1)
|
||||
NE = (-1, 1)
|
||||
SE = (1, 1)
|
||||
SW = (1, -1)
|
||||
|
||||
def __init__(self, text: str):
|
||||
lines = [line for line in text.splitlines() if line.strip() != ""]
|
||||
self.grid = list(map(list, lines))
|
||||
@@ -64,13 +63,10 @@ class Grid2D:
|
||||
for col_i in range(self.n_cols)]
|
||||
|
||||
def find(self, chars: str) -> list[tuple[int, int]]:
|
||||
r = []
|
||||
for row_i in range(self.n_rows):
|
||||
for col_i in range(self.n_cols):
|
||||
c = (row_i, col_i)
|
||||
if self[c] in chars:
|
||||
r.append(c)
|
||||
return r
|
||||
return [c for c in self.all_coords() if self[c] in chars]
|
||||
|
||||
def find_not(self, chars: str) -> list[tuple[int, int]]:
|
||||
return [c for c in self.all_coords() if self[c] not in chars]
|
||||
|
||||
def all_coords(self) -> list[tuple[int, int]]:
|
||||
return [(row_i, col_i)
|
||||
@@ -89,17 +85,27 @@ class Grid2D:
|
||||
row, col = pos
|
||||
return row >= 0 and row < self.n_rows and col >= 0 and col < self.n_cols
|
||||
|
||||
def __contains__(self, pos: tuple[int, int]) -> bool:
|
||||
return self.contains(pos)
|
||||
|
||||
def neighbors_ort(self, pos: tuple[int, int]) -> list[tuple[int, int]]:
|
||||
ort_rel = [(-1, 0), (0, 1), (1, 0), (0, -1)]
|
||||
return [add2(pos, off) for off in ort_rel if self.contains(add2(pos, off))]
|
||||
return [add2(pos, off) for off in self.dirs_ort() if self.contains(add2(pos, off))]
|
||||
|
||||
def neighbors_vert(self, pos: tuple[int, int]) -> list[tuple[int, int]]:
|
||||
ort_vert = [(-1, -1), (-1, 1), (1, 1), (1, -1)]
|
||||
return [add2(pos, off) for off in ort_vert if self.contains(add2(pos, off))]
|
||||
return [add2(pos, off) for off in self.dirs_vert() if self.contains(add2(pos, off))]
|
||||
|
||||
def neighbors_adj(self, pos: tuple[int, int]) -> list[tuple[int, int]]:
|
||||
return self.neighbors_ort(pos) + self.neighbors_vert(pos)
|
||||
|
||||
def flip_ort(self, pos: tuple[int, int]) -> tuple[int, int]:
|
||||
return (-pos[0], -pos[1])
|
||||
|
||||
def dirs_ort(self) -> list[tuple[int, int]]:
|
||||
return [self.N, self.E, self.S, self.W]
|
||||
|
||||
def dirs_vert(self) -> list[tuple[int, int]]:
|
||||
return [self.NE, self.SE, self.SW, self.NW]
|
||||
|
||||
def print(self):
|
||||
for r in self.rows():
|
||||
print("".join(r))
|
||||
|
||||
Reference in New Issue
Block a user