Beispiel #1
0
def draw_coordinates(
    coordinates: Iterable[Pos],
    including_areas: bool = False,
    distance_limit: int = None,
    bounds: Rect = Rect.at_origin(10, 10),
    empty_char: str = '·',
    safe_char: str = '#',
) -> None:
    coordinates_list = list(coordinates)

    # draw points
    canvas = dict(zip(coordinates_list, string.ascii_uppercase))

    if including_areas:
        # draw claims for part 1
        areas = claim_areas(coordinates_list, include_infinite=True)
        canvas.update((area_pos, canvas[pos].lower())
                      for pos, area in areas.items() for area_pos in area
                      if area_pos not in canvas)

    elif distance_limit is not None:
        # draw safe region for part 2
        region = safe_region(coordinates_list, distance_limit)
        canvas.update((pos, safe_char) for pos in region if pos not in canvas)

    for y in bounds.range_y():
        print("".join(
            canvas.get((x, y), empty_char) for x in bounds.range_x()))
    def from_lines(cls, lines: Iterable[str]):
        height, width = 0, None
        trees: set[Pos] = set()

        for y, line in enumerate(lines):
            line = line.strip()
            assert all(ch in (cls.TREE_CHAR, cls.OPEN_CHAR) for ch in line)

            height += 1
            if width is None:
                # width is determined by the length of the first line
                width = len(line)
            else:
                # all lines must have the equal length
                assert width == len(line)

            trees.update(
                (x, y)
                for x, ch in enumerate(line)
                if ch == cls.TREE_CHAR
            )

        if width is None:
            raise ValueError("no lines")

        return cls(
            trees=trees,
            bounds=Rect.at_origin(width=width, height=height)
        )
Beispiel #3
0
    def load(cls, fn: str):
        with open(fn) as file:
            lines = [line.rstrip() for line in file]

        height = len(lines)
        assert height > 0
        width = single_value(set(len(line) for line in lines))

        board = {(x, y): c
                 for y, line in enumerate(lines) for x, c in enumerate(line)}

        return cls(board, Rect.at_origin(width, height))
Beispiel #4
0
    def __init__(self,
                 width: int,
                 height: int,
                 lights_on: Iterable[Pos],
                 *,
                 lights_stuck_on: Iterable[Pos] = ()):
        assert width > 0
        assert height > 0

        self.bounds = Rect.at_origin(width, height)
        self.lights_stuck_on = set(lights_stuck_on)
        self.lights_on = set(lights_on) | self.lights_stuck_on

        assert all(pos in self.bounds for pos in self.lights_on)
        assert all(pos in self.bounds for pos in self.lights_stuck_on)
Beispiel #5
0
 def __init__(self,
              width: int = 50,
              height: int = 6,
              pixels_on: Iterable[Pos] = None):
     self.bounds = Rect.at_origin(width, height)
     self.pixels_on: set[Pos] = set(pixels_on) if pixels_on else set()
Beispiel #6
0
        except StopIteration as stop:
            raise KeyError(letter) from stop

    @classmethod
    def from_path(cls, path: str) -> Iterable['Direction']:
        return (cls.from_letter(letter) for letter in path)

    def __add__(self, other):
        x, y = other
        return x + self.dx, y + self.dy

    def __radd__(self, other):
        return self + other


BOUNDS = Rect.at_origin(4, 4)


def walk(path: str, start: Pos = BOUNDS.top_left) -> Pos:
    pos = start

    for step in Direction.from_path(path):
        pos += step
        assert pos in BOUNDS

    return pos


class Room():
    def __init__(self, path: str = '', pos: Pos = None):
        self.path = path