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
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)