def irsk(pi, n=None):
    if n is None:
        n = pi.rank
    cycles = sorted([(pi(i), i) for i in range(1, n + 1) if i <= pi(i)])
    tab = Tableau()
    for b, a in cycles:
        if a == b:
            tab = tab.add(1, tab.max_column() + 1, a)
        else:
            p, q = InsertionAlgorithm.hecke(tab.row_reading_word() + (a, ))
            i, j = q.find(len(q))[0]
            while j > 1 and (i + 1, j - 1) not in p:
                j = j - 1
            tab = p.add(i + 1, j, b)
    return tab
예제 #2
0
class InsertionState:

    def __init__(self, tableau=None, outer=None):
        self.tableau = Tableau() if tableau is None else tableau
        self.outer = outer
        self.inner_dimensions = self._get_inner_dimensions()

    def _get_inner_dimensions(self):
        if self.outer:
            i, j = self.outer
            t = self.tableau.remove(i, j)
        else:
            t = self.tableau
        m, n = t.max_row(), t.max_column()

        if self.outer:
            i, j = self.outer
            assert {True, False} == {m + 2 == i, n + 2 == j}
        return m, n

    def __eq__(self, other):
        assert type(other) == type(self)
        return self.tableau == other.tableau and self.outer == other.outer

    def __hash__(self):
        return hash((self.tableau, self.outer))

    def __repr__(self):
        return str(self.tableau)

    def __contains__(self, box):
        return box in self.tableau

    def __iter__(self):
        return self.tableau.__iter__()

    @property
    def boxes(self):
        return self.tableau.boxes

    def is_initial(self):
        return self.outer is not None and self.outer[0] == 1

    def is_terminal(self):
        return self.outer is None

    def get(self, i, j, default=None):
        return self.tableau.get(i, j, default)

    def add(self, a):
        assert self.outer is None
        n = self.tableau.max_column() + 2
        tableau = self.tableau.add(1, n, a)
        outer = (1, n)
        return self.__class__(tableau, outer)

    def has_outer_box_in_last_row(self):
        return self.outer and self.outer[0] == self.inner_dimensions[0] + 2

    def has_outer_box_in_last_column(self):
        return self.outer and self.outer[1] == self.inner_dimensions[1] + 2

    def pop(self):
        """
        Returns pair (t, v) where t is the tableau formed by removing the outer box
        and v is value in the outer box. Raises exception if state is terminal.
        """
        assert self.outer is not None
        i, j = self.outer
        return self.tableau.remove(i, j), self.get(i, j)

    def next(self):
        raise NotImplementedError

    def path(self):
        state = self
        while True:
            next_state, bumped = state.next()
            if bumped is None:
                return
            yield next_state, bumped
            state = next_state

    def insert(self, a):
        assert self.is_terminal()
        state = self.add(a)
        path = list(state.path())
        bumping_path = [box for _, box in path]
        final_state = path[-1][0]
        return final_state, bumping_path