Ejemplo n.º 1
0
 def is_crossing_len2(self, gp: GriddedPerm) -> bool:
     """
     Return True if the gridded permutation `gp` is a length 2 obstruction
     crossing between the first and second cell.
     """
     return (
         len(gp) == 2
         and gp.occupies(self.first_cell)
         and gp.occupies(self.second_cell)
     )
Ejemplo n.º 2
0
 def new_assumption(self):
     """
     Return the assumption that needs to be counted in order to enumerate.
     """
     fcell = self.first_cell
     scell = self.second_cell
     gps = (GriddedPerm.single_cell(Perm((0,)), fcell),)
     if self._fuse_row:
         sum_ob = GriddedPerm(Perm((1, 0)), (scell, fcell))
     else:
         sum_ob = GriddedPerm(Perm((1, 0)), (fcell, scell))
     if sum_ob in self._tiling.obstructions:
         return SumComponentAssumption(gps)
     return SkewComponentAssumption(gps)
Ejemplo n.º 3
0
 def positive_left_right_requirements(self):
     """
     Return the pair of requirements that ensures the left contains at least
     one point, and the right contains at least one point.
     """
     left, right = [], []
     for (x, y) in self._tiling.active_cells:
         if self._fuse_row and y == self._row_idx:
             left.append(GriddedPerm.single_cell(Perm((0,)), (x, y)))
             right.append(GriddedPerm.single_cell(Perm((0,)), (x, y + 1)))
         if not self._fuse_row and x == self._col_idx:
             left.append(GriddedPerm.single_cell(Perm((0,)), (x, y)))
             right.append(GriddedPerm.single_cell(Perm((0,)), (x + 1, y)))
     return tuple(sorted(left)), tuple(sorted(right))
Ejemplo n.º 4
0
def _get_cell_insertion_input(
) -> Tuple[Tiling, VerificationTactics, GriddedPerm]:
    data = _get_request_json()
    try:
        tiling = decode_key(data["tiling"])
        verification_tactics = VerificationTactics.from_response_dictionary(
            data["verify"])
        x: int = data["x"]
        y: int = data["y"]
        patt: str = data["patt"]
    except (TypeError, KeyError, ValueError, TilingDecodeException) as exc:
        raise BadRequest() from exc
    if not (isinstance(x, int) and isinstance(y, int)
            and isinstance(patt, str)):
        raise BadRequest()
    if not patt.isdecimal():
        raise BadRequest()
    _x, _y = tiling.dimensions
    if x < 0 or x >= _x or y < 0 or y >= _y:
        raise BadRequest()
    n, value_set = len(patt), set(map(int, patt))
    if len(value_set) != n or not all(
            i in value_set
            for i in (range(n) if 0 in value_set else range(1, n + 1))):
        raise BadRequest()
    return (
        tiling,
        verification_tactics,
        GriddedPerm.single_cell(Perm.to_standard(patt), (x, y)),
    )
Ejemplo n.º 5
0
 def insert_next_point(
     self,
     gp: GriddedPerm,
     col: int,
 ) -> Iterator[GriddedPerm]:
     """
     Insert the next point in the given column in all possible way.
     """
     active_cell_in_col = (cell for cell in self._active_cells
                           if cell[0] == col)
     for cell in active_cell_in_col:
         _, _, minval, maxval = gp.get_bounding_box(cell)
         for val in range(minval, maxval + 1):
             next_gp = GriddedPerm(gp.patt.insert(new_element=val),
                                   gp.pos + (cell, ))
             yield next_gp
Ejemplo n.º 6
0
def guess_obstructions(gps: Iterable[GriddedPerm],
                       max_len: int = -1) -> Set[GriddedPerm]:
    """Generate minimal obstructions avoided by the provided gridded perms,
    if possible. We check to a fixed length."""
    gps = set(gps)
    c, r, longest = _get_dimensions(gps)
    max_len = longest if max_len == -1 else min(max_len, longest)
    return _search(deque([GriddedPerm()]), gps, c, r, max_len)
Ejemplo n.º 7
0
 def has_crossing_len2_ob(self):
     """
     Return True if the tiling contains a crossing length 2 obstruction
     between `self.first_cell` and `self.second_cell`.
     """
     fcell = self.first_cell
     scell = self.second_cell
     if self._fuse_row:
         possible_obs = [
             GriddedPerm(Perm((0, 1)), (fcell, scell)),
             GriddedPerm(Perm((1, 0)), (scell, fcell)),
         ]
     else:
         possible_obs = [
             GriddedPerm(Perm((0, 1)), (fcell, scell)),
             GriddedPerm(Perm((1, 0)), (fcell, scell)),
         ]
     return any(ob in possible_obs for ob in self._tiling.obstructions)
Ejemplo n.º 8
0
 def new_assumption(self):
     """
     Return the assumption that needs to counted in order to enumerate.
     """
     return TrackingAssumption(
         GriddedPerm.single_cell(Perm((0,)), cell)
         for cell in self._tiling.active_cells
         if (self._fuse_row and cell[1] == self._row_idx)
         or (not self._fuse_row and cell[0] == self._col_idx)
     )
Ejemplo n.º 9
0
    def unfuse_gridded_perm(
        self, gp: GriddedPerm, left_points: Optional[int] = None
    ) -> Iterator[GriddedPerm]:
        """
        Generator of all the possible ways to unfuse a gridded permutations.

        If left_points is given, the iterator contains only one gridded
        permutations with said number of left points.
        """

        def stretch_above(p):
            return p if p[1] < self._row_idx else (p[0], p[1] + 1)

        def stretch_left(p):
            return p if p[0] < self._col_idx else (p[0] + 1, p[1])

        if self._fuse_row:
            stretch = stretch_above
            editable_pos_idx = [
                i for i, p in enumerate(gp.pos) if p[1] == self._row_idx
            ]
            editable_pos_idx.sort(key=lambda i: gp.patt[i])
        else:
            stretch = stretch_left
            editable_pos_idx = [
                i for i, p in enumerate(gp.pos) if p[0] == self._col_idx
            ]
            editable_pos_idx.sort()

        pos = list(map(stretch, gp.pos))
        if left_points is None or left_points == 0:
            yield gp.__class__(gp.patt, pos)
        if left_points == 0:
            return
        row_shift = int(self._fuse_row)
        col_shift = 1 - int(self._fuse_row)
        for left_points_so_far, i in enumerate(editable_pos_idx):
            pos[i] = (pos[i][0] - col_shift, pos[i][1] - row_shift)
            if left_points is None or left_points_so_far + 1 == left_points:
                yield gp.__class__(gp.patt, pos)
            if left_points_so_far + 1 == left_points:
                break
Ejemplo n.º 10
0
 def new_positive_requirement(self):
     cells = [
         (x, y)
         for (x, y) in self._tiling.active_cells
         if (self._fuse_row and y == self._row_idx)
         or (not self._fuse_row and x == self._col_idx)
     ]
     if self._positive_left and self._positive_right:
         cells.sort()
         res = []
         for idx, c1 in enumerate(cells):
             for c2 in cells[idx:]:
                 res.append(GriddedPerm(Perm((0, 1)), (c1, c2)))
                 if self._fuse_row:
                     res.append(GriddedPerm(Perm((1, 0)), (c1, c2)))
                 else:
                     res.append(GriddedPerm(Perm((1, 0)), (c2, c1)))
         return sorted(res)
     if self._positive_left or self._positive_right:
         return sorted(GriddedPerm.single_cell(Perm((0,)), cell) for cell in cells)
     raise ValueError("no positive left right requirement")
Ejemplo n.º 11
0
 def fuse_gridded_perm(self, gp: GriddedPerm) -> GriddedPerm:
     """
     Fuse the gridded permutation `gp`.
     """
     fused_pos = []
     for x, y in gp.pos:
         if self._fuse_row and y > self._row_idx:
             y -= 1
         elif not self._fuse_row and x > self._col_idx:
             x -= 1
         fused_pos.append((x, y))
     return gp.__class__(gp.patt, fused_pos)
Ejemplo n.º 12
0
def _get_add_assumption_input(
) -> Tuple[Tiling, VerificationTactics, List[GriddedPerm]]:
    data = _get_request_json()
    try:
        tiling = decode_key(data["tiling"])
        verification_tactics = VerificationTactics.from_response_dictionary(
            data["verify"])
        pos: List[List[int]] = data["pos"]
    except (TypeError, KeyError, ValueError, TilingDecodeException) as exc:
        raise BadRequest() from exc
    if not isinstance(pos, list) or len(pos) == 0:
        raise BadRequest()
    _x, _y = tiling.dimensions
    gps: List[GriddedPerm] = []
    for coord in pos:
        if not isinstance(coord, list) or len(coord) != 2:
            raise BadRequest()
        x, y = coord
        if not (isinstance(x, int) and isinstance(y, int)):
            raise BadRequest()
        if x < 0 or y < 0 or x >= _x or y >= _y:
            raise BadRequest()
        gps.append(GriddedPerm.single_cell((0, ), (x, y)))
    return tiling, verification_tactics, gps
Ejemplo n.º 13
0
 def __iter__(self) -> Iterator[GriddedPerm]:
     if not GriddedPerm(Perm(tuple()), tuple()) in self._obstructions:
         yield from self.backtracking(GriddedPerm.empty_perm(), 0,
                                      self._requirements)
Ejemplo n.º 14
0
 def can_satisfy(gp: GriddedPerm, col: int, req: GriddedPerm) -> bool:
     return req.get_subperm_left_col(col) in gp