Grid.from_data()

This commit is contained in:
Stefan Harmuth 2023-12-03 14:34:08 +01:00
parent e54e7afd6c
commit af443c94b2

View File

@ -1,11 +1,15 @@
from __future__ import annotations
import re
from collections import deque
from collections.abc import Callable
from .aoc_ocr import convert_array_6
from .coordinate import Coordinate, DistanceAlgorithm, Shape
from enum import Enum
from heapq import heappop, heappush
from math import inf
from typing import Any, Dict, List
from typing import Any, Dict, List, Iterable, Mapping
OFF = False
ON = True
@ -620,6 +624,57 @@ class Grid:
return ret
@classmethod
def from_data(
cls,
data: Iterable[Iterable],
default: Any = False,
translate: Mapping[str, Any] = None,
gen_3d: bool = False,
) -> Grid:
"""
Every entry in data will be treated as row, every entry in data[entry] will be a separate column.
gen_3d = True will just add z=0 to every Coordinate
translate is used on every data[entry] and if present as key, its value will be used instead
a value in translate can be a function with the following signature: def translate(value: Any) -> Any
a key in translate is either a string of len 1 or it will be treated as regexp
if multiple regexp match, the first encountered wins
if there is a key that matches the entry it wins over any mathing regexp
"""
grid = cls(default=default)
regex_in_translate = False
if translate is not None:
for k in translate:
if len(k) > 1:
regex_in_translate = True
for y, row in enumerate(data):
for x, col in enumerate(row):
if translate is not None and col in translate:
if isinstance(col, Callable):
col = translate[col](col)
else:
col = translate[col]
elif regex_in_translate:
for k, v in translate.items():
if len(k) == 1:
continue
if re.search(k, col):
if isinstance(v, Callable):
col = translate[k](col)
else:
col = v
break
if gen_3d:
grid.set(Coordinate(x, y, 0), col)
else:
grid.set(Coordinate(x, y), col)
return grid
def __eq__(self, other: Grid) -> bool:
if not isinstance(other, Grid):
return False