예제 #1
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
예제 #2
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)