AdventOfCode/2019/grid.py

56 lines
1.6 KiB
Python
Raw Normal View History

2019-12-18 12:09:12 +01:00
"""Generic 2D grid with a few helpers."""
2019-12-17 18:16:26 +01:00
from collections import defaultdict
class Grid:
2019-12-18 18:01:42 +01:00
def __init__(self, value_factory=int, lines=None):
self.g = defaultdict(lambda: defaultdict(value_factory))
2019-12-18 12:09:12 +01:00
if lines:
self.load(lines)
2019-12-17 18:16:26 +01:00
2019-12-18 12:09:12 +01:00
def getv(self, x, y):
return self.g[y][x]
2020-11-16 17:13:13 +01:00
2019-12-18 12:09:12 +01:00
def setv(self, x, y, value):
self.g[y][x] = value
2019-12-18 02:04:40 +01:00
2019-12-18 18:01:42 +01:00
def load(self, lines, f=lambda v: v):
for y, line in enumerate(lines):
for x, c in enumerate(line.rstrip()):
self.g[y][x] = f(c)
def values_gen(self):
for y, row in self.g.items():
for x, v in row.items():
yield (x, y, v)
def near_objects(self, p):
2019-12-18 02:04:40 +01:00
"""Return a dict of neighbor positions to values (U, L, D, R)."""
2019-12-18 18:01:42 +01:00
return {q: self.g[q[1]][q[0]] for q in Grid.near(p)}
2019-12-18 02:04:40 +01:00
2019-12-18 12:09:12 +01:00
def dumb_print(self, f=lambda v: v):
for row in self.g.values():
for x in row.values():
print(f(x), end="")
print()
2019-12-18 18:01:42 +01:00
def print_near(self, p, view_size=2):
2019-12-19 00:21:45 +01:00
"""Print near values in an area of view_size. Works iff keys support addition."""
2019-12-18 18:01:42 +01:00
for dy in range(-view_size, view_size + 1):
print("".join([
self.g[p[1] + dy][p[0] + dx]
for dx in range(-view_size, view_size + 1)
]))
2019-12-18 12:09:12 +01:00
@staticmethod
def near(p):
"""Return a tuple of neighbor positions (up, left, down, right)."""
return (
(p[0] , p[1] - 1),
(p[0] + 1, p[1] ),
(p[0] , p[1] + 1),
(p[0] - 1, p[1] ),
)