
    wgV                       d dl Z d dlmZ d dlmZ d dlmZ d dlmZ d dl	m
Z
 d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZmZmZmZmZmZ d dlm Z  d dl!m"Z" d dl#m$Z$ d Z%d Z&d Z'd Z(d Z)d Z* G d de+      Z, G d de
      Z-d Z.e-Z/e/j`                  Z0 G d de      Z1 e$e-e-      d        Z2y)     N)defaultdict)Iterable)reduce)global_parameters)Atom)Expr)
int_valued)Integer)_sympify)zeros)lcmsrepr)flattenhas_varietyminlexhas_dupsrunsis_sequenceas_int)ifac)dispatchc                 2    |D cg c]  }| |   	 c}S c c}w )aM  
    Return the product b*a; input and output are array forms. The ith value
    is a[b[i]].

    Examples
    ========

    >>> from sympy.combinatorics.permutations import _af_rmul, Permutation

    >>> a, b = [1, 0, 2], [0, 2, 1]
    >>> _af_rmul(a, b)
    [1, 2, 0]
    >>> [a[b[i]] for i in range(3)]
    [1, 2, 0]

    This handles the operands in reverse order compared to the ``*`` operator:

    >>> a = Permutation(a)
    >>> b = Permutation(b)
    >>> list(a*b)
    [2, 0, 1]
    >>> [b(a(i)) for i in range(3)]
    [2, 0, 1]

    See Also
    ========

    rmul, _af_rmuln
     )abis      e/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/combinatorics/permutations.py_af_rmulr       s    < QAaDs   c                  B   | }t        |      }|dk(  r|\  }}}|D cg c]
  }|||       c}S |dk(  r |\  }}}}|D cg c]  }||||          c}S |dk(  r$|\  }}}}}|D cg c]  }|||||             c}S |dk(  r(|\  }}}}}}	|	D cg c]  }||||||                c}S |dk(  r,|\  }}}}}}	}
|
D cg c]  }||||||	|                   c}S |dk(  r0|\  }}}}}}	}
}|D cg c]  }||||||	|
|                      c}S |dk(  r|d   d	d	 S |d
k(  r|\  }}|D cg c]  }||   	 c}S |dk(  rt        d      t        |d	|d
z    }t        ||d
z  d	  }|D cg c]  }||   	 c}S c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}w )aV  
    Given [a, b, c, ...] return the product of ...*c*b*a using array forms.
    The ith value is a[b[c[i]]].

    Examples
    ========

    >>> from sympy.combinatorics.permutations import _af_rmul, Permutation

    >>> a, b = [1, 0, 2], [0, 2, 1]
    >>> _af_rmul(a, b)
    [1, 2, 0]
    >>> [a[b[i]] for i in range(3)]
    [1, 2, 0]

    This handles the operands in reverse order compared to the ``*`` operator:

    >>> a = Permutation(a); b = Permutation(b)
    >>> list(a*b)
    [2, 0, 1]
    >>> [b(a(i)) for i in range(3)]
    [2, 0, 1]

    See Also
    ========

    rmul, _af_rmul
                         r   N   zString must not be empty)len
ValueError	_af_rmuln)abcr   mp0p1p2r   p3p4p5p6p7r   s                r   r,   r,   6   s-   : 	AAAAv
B#%&a2a5	&&AvBB')*!2be9**AvBB+-.a2bAi=!..Av!"BBB/12!2bBqEm$%22Av%&"BBB356a2bBr!uI'()66Av)*&BBBB79:!2bBr"Q%yM*+,-::AvtAwAv1 !  Av344	Aeq!tH	B	AadeH	BaBqE3 ' + / 3 7 ;
 !
 s.   E9E>%FF=F/F+F*Fc                     t        |       }dg|z  }d}t        |      D ]3  }||   dk(  s|dz  }d||<   |}| |   |k7  s!| |   }d||<   | |   |k7  r5 ||z
  dz  S )a  
    Computes the parity of a permutation in array form.

    Explanation
    ===========

    The parity of a permutation reflects the parity of the
    number of inversions in the permutation, i.e., the
    number of pairs of x and y such that x > y but p[x] < p[y].

    Examples
    ========

    >>> from sympy.combinatorics.permutations import _af_parity
    >>> _af_parity([0, 1, 2, 3])
    0
    >>> _af_parity([3, 2, 0, 1])
    1

    See Also
    ========

    Permutation
    r   r(   r)   )r*   range)pinr   cjr   s         r   
_af_parityr=   s   s    2 	BA	
aA	A1X Q419FAAaDAQ%1*qE! Q%1* EQ;    c                 T    dgt        |       z  }t        |       D ]
  \  }}|||<    |S )aP  
    Finds the inverse, ~A, of a permutation, A, given in array form.

    Examples
    ========

    >>> from sympy.combinatorics.permutations import _af_invert, _af_rmul
    >>> A = [1, 2, 0, 3]
    >>> _af_invert(A)
    [2, 0, 1, 3]
    >>> _af_rmul(_, A)
    [0, 1, 2, 3]

    See Also
    ========

    Permutation, __invert__
    r   )r*   	enumerate)r   inv_formr   ais       r   
_af_invertrC      s8    & sSV|H1 2Or>   c                 ~   |dk(  rt        t        t        |                   S |dk  rt        t	        |       |       S |dk(  r| dd S |dk(  r| D cg c]  }| |   	 }}|S |dk(  r| D cg c]
  }| | |       }}|S |dk(  r| D cg c]  }| | | |          }}|S t        t        t        |                   }	 |dz  r| D cg c]  }||   	 }}|dz  }|s	 |S |dz  dk(  r| D cg c]  }| | | |          } }|dz  }n|dz  dk(  r| D cg c]  }| |   	 } }|dz  }gc c}w c c}w c c}w c c}w c c}w c c}w )a4  
    Routine for finding powers of a permutation.

    Examples
    ========

    >>> from sympy.combinatorics import Permutation
    >>> from sympy.combinatorics.permutations import _af_pow
    >>> p = Permutation([2, 0, 3, 1])
    >>> p.order()
    4
    >>> _af_pow(p._array_form, 4)
    [0, 1, 2, 3]
    r   r(   Nr)   r"   r#   )listr8   r*   _af_powrC   )r   r:   r   r   s       r   rF   rF      s    	AvE#a&M""1uz!}qb))Avt	
aaQqT( H' 
a QqtW  $ H# 
a!"#AQq1wZ##  H s1v1u#$%aQqT%%Q H 1uz)*+AQq1wZ++FQ!#$%aQqT%%F   # &
 , &s$   D!*D&D+D0'D5D:c                 \     t         fdt        t               dz
        D               S )a7  
    Checks if the two permutations with array forms
    given by ``a`` and ``b`` commute.

    Examples
    ========

    >>> from sympy.combinatorics.permutations import _af_commutes_with
    >>> _af_commutes_with([1, 2, 0], [0, 2, 1])
    False

    See Also
    ========

    Permutation, commutes_with
    c              3   @   K   | ]  }|      |      k7    y wNr   .0r   r   r   s     r   	<genexpr>z$_af_commutes_with.<locals>.<genexpr>   s&     A!1QqT7a!g%As   r(   )anyr8   r*   )r   r   s   ``r   _af_commutes_withrN      s&    " AuSVaZ/@AAAAr>   c                   R    e Zd ZdZd Zd Zd ZddZd Zd Z	d	 Z
ed
        Zd Zy)Cyclea7  
    Wrapper around dict which provides the functionality of a disjoint cycle.

    Explanation
    ===========

    A cycle shows the rule to use to move subsets of elements to obtain
    a permutation. The Cycle class is more flexible than Permutation in
    that 1) all elements need not be present in order to investigate how
    multiple cycles act in sequence and 2) it can contain singletons:

    >>> from sympy.combinatorics.permutations import Perm, Cycle

    A Cycle will automatically parse a cycle given as a tuple on the rhs:

    >>> Cycle(1, 2)(2, 3)
    (1 3 2)

    The identity cycle, Cycle(), can be used to start a product:

    >>> Cycle()(1, 2)(2, 3)
    (1 3 2)

    The array form of a Cycle can be obtained by calling the list
    method (or passing it to the list function) and all elements from
    0 will be shown:

    >>> a = Cycle(1, 2)
    >>> a.list()
    [0, 2, 1]
    >>> list(a)
    [0, 2, 1]

    If a larger (or smaller) range is desired use the list method and
    provide the desired size -- but the Cycle cannot be truncated to
    a size smaller than the largest element that is out of place:

    >>> b = Cycle(2, 4)(1, 2)(3, 1, 4)(1, 3)
    >>> b.list()
    [0, 2, 1, 3, 4]
    >>> b.list(b.size + 1)
    [0, 2, 1, 3, 4, 5]
    >>> b.list(-1)
    [0, 2, 1]

    Singletons are not shown when printing with one exception: the largest
    element is always shown -- as a singleton if necessary:

    >>> Cycle(1, 4, 10)(4, 5)
    (1 5 4 10)
    >>> Cycle(1, 2)(4)(5)(10)
    (1 2)(10)

    The array form can be used to instantiate a Permutation so other
    properties of the permutation can be investigated:

    >>> Perm(Cycle(1, 2)(3, 4).list()).transpositions()
    [(1, 2), (3, 4)]

    Notes
    =====

    The underlying structure of the Cycle is a dictionary and although
    the __iter__ method has been redefined to give the array form of the
    cycle, the underlying dictionary items are still available with the
    such methods as items():

    >>> list(Cycle(1, 2).items())
    [(1, 2), (2, 1)]

    See Also
    ========

    Permutation
    c                     t        |      S )z)Enter arg into dictionary and return arg.r   )selfargs     r   __missing__zCycle.__missing__@  s    c{r>   c              #   @   K   | j                         E d {    y 7 wrI   )rE   rR   s    r   __iter__zCycle.__iter__D  s     99;s   c           	          t        | }t        t        | j                               | j                         D cg c]
  }|| |       c}      D ]
  \  }}|||<    |S c c}w )a  Return product of cycles processed from R to L.

        Examples
        ========

        >>> from sympy.combinatorics import Cycle
        >>> Cycle(1, 2)(2, 3)
        (1 3 2)

        An instance of a Cycle will automatically parse list-like
        objects and Permutations that are on the right. It is more
        flexible than the Permutation in that all elements need not
        be present:

        >>> a = Cycle(1, 2)
        >>> a(2, 3)
        (1 3 2)
        >>> a(2, 3)(4, 5)
        (1 3 2)(4 5)

        )rP   ziprE   keys)rR   otherrvkvs        r   __call__zCycle.__call__G  s_    , E]TYY[)+MABtAwK+MN 	DAqBqE		 ,Ns   A
Nc                    | s|t        d      |Dt        | j                         D cg c]  }| |   |k7  s| c}dgz         }t        ||dz         }n| j                  }t	        |      D cg c]  }| |   	 c}S c c}w c c}w )a  Return the cycles as an explicit list starting from 0 up
        to the greater of the largest value in the cycles and size.

        Truncation of trailing unmoved items will occur when size
        is less than the maximum element in the cycle; if this is
        desired, setting ``size=-1`` will guarantee such trimming.

        Examples
        ========

        >>> from sympy.combinatorics import Cycle
        >>> p = Cycle(2, 3)(4, 5)
        >>> p.list()
        [0, 1, 3, 2, 5, 4]
        >>> p.list(10)
        [0, 1, 3, 2, 5, 4, 6, 7, 8, 9]

        Passing a length too small will trim trailing, unchanged elements
        in the permutation:

        >>> Cycle(2, 4)(1, 2, 4).list(-1)
        [0, 2, 1]
        must give size for empty Cycler   r(   )r+   maxrZ   sizer8   )rR   rc   r   bigs       r   rE   z
Cycle.listb  s    0 =>>$))+>QaAq>!DECtS1W%D99D!&t-AQ--	 ? .s   A>A>/Bc                     | syt        |       j                  }dj                  d |D              }| j                  dz
  t	        fd|D              s|dz  z  }d|z  S )a  We want it to print as a Cycle, not as a dict.

        Examples
        ========

        >>> from sympy.combinatorics import Cycle
        >>> Cycle(1, 2)
        (1 2)
        >>> print(_)
        (1 2)
        >>> list(Cycle(1, 2).items())
        [(1, 2), (2, 1)]
        zCycle() c              3   D   K   | ]  }t        t        |              y wrI   strtuplerK   r;   s     r   rL   z!Cycle.__repr__.<locals>.<genexpr>       2aCaM2    r(   c              3   6   K   | ]  }|D ]	  }|k(     y wrI   r   rK   r;   r   rd   s      r   rL   z!Cycle.__repr__.<locals>.<genexpr>  !     7Q718787   (%s)zCycle%s)Permutationcyclic_formjoinrc   rM   rR   cyclessrd   s      @r   __repr__zCycle.__repr__  sb     T"..GG2622ii!m7V77#A1}r>   c                     | syt        |       j                  }dj                  d |D              }| j                  dz
  t	        fd|D              s|dz  z  }|j                  dd      }|S )a	  We want it to be printed in a Cycle notation with no
        comma in-between.

        Examples
        ========

        >>> from sympy.combinatorics import Cycle
        >>> Cycle(1, 2)
        (1 2)
        >>> Cycle(1, 2, 4)(5, 6)
        (1 2 4)(5 6)
        z()rf   c              3   D   K   | ]  }t        t        |              y wrI   rh   rk   s     r   rL   z Cycle.__str__.<locals>.<genexpr>  rl   rm   r(   c              3   6   K   | ]  }|D ]	  }|k(     y wrI   r   ro   s      r   rL   z Cycle.__str__.<locals>.<genexpr>  rp   rq   rr   ,)rs   rt   ru   rc   rM   replacerv   s      @r   __str__zCycle.__str__  sm     T"..GG2622ii!m7V77#AIIc2r>   c                    |syt        |      dk(  rpt        |d   t              r)|d   j                  D ]  }| j	                   | |         yt        |d   t
              r!|d   j                         D ]
  \  }}|| |<    y|D cg c]  }t        |       }}t        d |D              rt        d      t        |      rt        d      t        t        |       d      D ]  }||dz      | ||   <    yc c}w )zLoad up a Cycle instance with the values for the cycle.

        Examples
        ========

        >>> from sympy.combinatorics import Cycle
        >>> Cycle(1, 2, 6)
        (1 2 6)
        Nr(   r   c              3   &   K   | ]	  }|d k    yw)r   Nr   )rK   r   s     r   rL   z!Cycle.__init__.<locals>.<genexpr>  s     #q1u#s   z-negative integers are not allowed in a cycle.z'All elements must be unique in a cycle.)r*   
isinstancers   rt   updaterP   itemsr   rM   r+   r   r8   )rR   argsr;   r]   r^   r   r   s          r   __init__zCycle.__init__  s     t9>$q';/a,, *AKKa)*DGU+ GMMO  DAqDG #'(aq	((#d##LMMD>FGGD	z1% 	(A QKDaM	( )s   C7c                 @    | syt        | j                               dz   S Nr   r(   )rb   rZ   rV   s    r   rc   z
Cycle.size  s    499;!##r>   c                     t        |       S rI   )rP   rV   s    r   copyz
Cycle.copy      T{r>   rI   )__name__
__module____qualname____doc__rT   rW   r_   rE   ry   r   r   propertyrc   r   r   r>   r   rP   rP      sF    JV6.B..(< $ $
r>   rP   c                       e Zd ZdZdZdZdZdZdZdZ	dddZ
e fd       Zd Zd Zd	 Zed
        ZdLdZed        Zed        Zed        Zd Zd Zd Zed        Zed        Zd Zd Zd Zd Zd Z d Z!d Z"d Z#edLd       Z$d Z%d Z&d Z'd  Z(d! Z)d" Z*d# Z+ed$        Z,dLd%Z-d& Z.d' Z/ed(        Z0d) Z1ed*        Z2ed+        Z3ed,        Z4ed-        Z5ed.        Z6ed/        Z7d0 Z8d1 Z9d2e:fd3Z;d2e:fd4Z<d5 Z=d6 Z>d7 Z?d8 Z@d9 ZAed:        ZBed;        ZCd< ZDd= ZEd> ZFd? ZGed@        ZHdA ZIdB ZJdC ZKdD ZLdE ZMdF ZNedMdG       ZOedH        ZPedI        ZQedJ        ZRdK ZSdZT xZUS )Nrs   a6  
    A permutation, alternatively known as an 'arrangement number' or 'ordering'
    is an arrangement of the elements of an ordered list into a one-to-one
    mapping with itself. The permutation of a given arrangement is given by
    indicating the positions of the elements after re-arrangement [2]_. For
    example, if one started with elements ``[x, y, a, b]`` (in that order) and
    they were reordered as ``[x, y, b, a]`` then the permutation would be
    ``[0, 1, 3, 2]``. Notice that (in SymPy) the first element is always referred
    to as 0 and the permutation uses the indices of the elements in the
    original ordering, not the elements ``(a, b, ...)`` themselves.

    >>> from sympy.combinatorics import Permutation
    >>> from sympy import init_printing
    >>> init_printing(perm_cyclic=False, pretty_print=False)

    Permutations Notation
    =====================

    Permutations are commonly represented in disjoint cycle or array forms.

    Array Notation and 2-line Form
    ------------------------------------

    In the 2-line form, the elements and their final positions are shown
    as a matrix with 2 rows:

    [0    1    2     ... n-1]
    [p(0) p(1) p(2)  ... p(n-1)]

    Since the first line is always ``range(n)``, where n is the size of p,
    it is sufficient to represent the permutation by the second line,
    referred to as the "array form" of the permutation. This is entered
    in brackets as the argument to the Permutation class:

    >>> p = Permutation([0, 2, 1]); p
    Permutation([0, 2, 1])

    Given i in range(p.size), the permutation maps i to i^p

    >>> [i^p for i in range(p.size)]
    [0, 2, 1]

    The composite of two permutations p*q means first apply p, then q, so
    i^(p*q) = (i^p)^q which is i^p^q according to Python precedence rules:

    >>> q = Permutation([2, 1, 0])
    >>> [i^p^q for i in range(3)]
    [2, 0, 1]
    >>> [i^(p*q) for i in range(3)]
    [2, 0, 1]

    One can use also the notation p(i) = i^p, but then the composition
    rule is (p*q)(i) = q(p(i)), not p(q(i)):

    >>> [(p*q)(i) for i in range(p.size)]
    [2, 0, 1]
    >>> [q(p(i)) for i in range(p.size)]
    [2, 0, 1]
    >>> [p(q(i)) for i in range(p.size)]
    [1, 2, 0]

    Disjoint Cycle Notation
    -----------------------

    In disjoint cycle notation, only the elements that have shifted are
    indicated.

    For example, [1, 3, 2, 0] can be represented as (0, 1, 3)(2).
    This can be understood from the 2 line format of the given permutation.
    In the 2-line form,
    [0    1    2   3]
    [1    3    2   0]

    The element in the 0th position is 1, so 0 -> 1. The element in the 1st
    position is three, so 1 -> 3. And the element in the third position is again
    0, so 3 -> 0. Thus, 0 -> 1 -> 3 -> 0, and 2 -> 2. Thus, this can be represented
    as 2 cycles: (0, 1, 3)(2).
    In common notation, singular cycles are not explicitly written as they can be
    inferred implicitly.

    Only the relative ordering of elements in a cycle matter:

    >>> Permutation(1,2,3) == Permutation(2,3,1) == Permutation(3,1,2)
    True

    The disjoint cycle notation is convenient when representing
    permutations that have several cycles in them:

    >>> Permutation(1, 2)(3, 5) == Permutation([[1, 2], [3, 5]])
    True

    It also provides some economy in entry when computing products of
    permutations that are written in disjoint cycle notation:

    >>> Permutation(1, 2)(1, 3)(2, 3)
    Permutation([0, 3, 2, 1])
    >>> _ == Permutation([[1, 2]])*Permutation([[1, 3]])*Permutation([[2, 3]])
    True

        Caution: when the cycles have common elements between them then the order
        in which the permutations are applied matters. This module applies
        the permutations from *left to right*.

        >>> Permutation(1, 2)(2, 3) == Permutation([(1, 2), (2, 3)])
        True
        >>> Permutation(1, 2)(2, 3).list()
        [0, 3, 1, 2]

        In the above case, (1,2) is computed before (2,3).
        As 0 -> 0, 0 -> 0, element in position 0 is 0.
        As 1 -> 2, 2 -> 3, element in position 1 is 3.
        As 2 -> 1, 1 -> 1, element in position 2 is 1.
        As 3 -> 3, 3 -> 2, element in position 3 is 2.

        If the first and second elements had been
        swapped first, followed by the swapping of the second
        and third, the result would have been [0, 2, 3, 1].
        If, you want to apply the cycles in the conventional
        right to left order, call the function with arguments in reverse order
        as demonstrated below:

        >>> Permutation([(1, 2), (2, 3)][::-1]).list()
        [0, 2, 3, 1]

    Entering a singleton in a permutation is a way to indicate the size of the
    permutation. The ``size`` keyword can also be used.

    Array-form entry:

    >>> Permutation([[1, 2], [9]])
    Permutation([0, 2, 1], size=10)
    >>> Permutation([[1, 2]], size=10)
    Permutation([0, 2, 1], size=10)

    Cyclic-form entry:

    >>> Permutation(1, 2, size=10)
    Permutation([0, 2, 1], size=10)
    >>> Permutation(9)(1, 2)
    Permutation([0, 2, 1], size=10)

    Caution: no singleton containing an element larger than the largest
    in any previous cycle can be entered. This is an important difference
    in how Permutation and Cycle handle the ``__call__`` syntax. A singleton
    argument at the start of a Permutation performs instantiation of the
    Permutation and is permitted:

    >>> Permutation(5)
    Permutation([], size=6)

    A singleton entered after instantiation is a call to the permutation
    -- a function call -- and if the argument is out of range it will
    trigger an error. For this reason, it is better to start the cycle
    with the singleton:

    The following fails because there is no element 3:

    >>> Permutation(1, 2)(3)
    Traceback (most recent call last):
    ...
    IndexError: list index out of range

    This is ok: only the call to an out of range singleton is prohibited;
    otherwise the permutation autosizes:

    >>> Permutation(3)(1, 2)
    Permutation([0, 2, 1, 3])
    >>> Permutation(1, 2)(3, 4) == Permutation(3, 4)(1, 2)
    True


    Equality testing
    ----------------

    The array forms must be the same in order for permutations to be equal:

    >>> Permutation([1, 0, 2, 3]) == Permutation([1, 0])
    False


    Identity Permutation
    --------------------

    The identity permutation is a permutation in which no element is out of
    place. It can be entered in a variety of ways. All the following create
    an identity permutation of size 4:

    >>> I = Permutation([0, 1, 2, 3])
    >>> all(p == I for p in [
    ... Permutation(3),
    ... Permutation(range(4)),
    ... Permutation([], size=4),
    ... Permutation(size=4)])
    True

    Watch out for entering the range *inside* a set of brackets (which is
    cycle notation):

    >>> I == Permutation([range(4)])
    False


    Permutation Printing
    ====================

    There are a few things to note about how Permutations are printed.

    .. deprecated:: 1.6

       Configuring Permutation printing by setting
       ``Permutation.print_cyclic`` is deprecated. Users should use the
       ``perm_cyclic`` flag to the printers, as described below.

    1) If you prefer one form (array or cycle) over another, you can set
    ``init_printing`` with the ``perm_cyclic`` flag.

    >>> from sympy import init_printing
    >>> p = Permutation(1, 2)(4, 5)(3, 4)
    >>> p
    Permutation([0, 2, 1, 4, 5, 3])

    >>> init_printing(perm_cyclic=True, pretty_print=False)
    >>> p
    (1 2)(3 4 5)

    2) Regardless of the setting, a list of elements in the array for cyclic
    form can be obtained and either of those can be copied and supplied as
    the argument to Permutation:

    >>> p.array_form
    [0, 2, 1, 4, 5, 3]
    >>> p.cyclic_form
    [[1, 2], [3, 4, 5]]
    >>> Permutation(_) == p
    True

    3) Printing is economical in that as little as possible is printed while
    retaining all information about the size of the permutation:

    >>> init_printing(perm_cyclic=False, pretty_print=False)
    >>> Permutation([1, 0, 2, 3])
    Permutation([1, 0, 2, 3])
    >>> Permutation([1, 0, 2, 3], size=20)
    Permutation([1, 0], size=20)
    >>> Permutation([1, 0, 2, 4, 3, 5, 6], size=20)
    Permutation([1, 0, 2, 4, 3], size=20)

    >>> p = Permutation([1, 0, 2, 3])
    >>> init_printing(perm_cyclic=True, pretty_print=False)
    >>> p
    (3)(0 1)
    >>> init_printing(perm_cyclic=False, pretty_print=False)

    The 2 was not printed but it is still there as can be seen with the
    array_form and size methods:

    >>> p.array_form
    [1, 0, 2, 3]
    >>> p.size
    4

    Short introduction to other methods
    ===================================

    The permutation can act as a bijective function, telling what element is
    located at a given position

    >>> q = Permutation([5, 2, 3, 4, 1, 0])
    >>> q.array_form[1] # the hard way
    2
    >>> q(1) # the easy way
    2
    >>> {i: q(i) for i in range(q.size)} # showing the bijection
    {0: 5, 1: 2, 2: 3, 3: 4, 4: 1, 5: 0}

    The full cyclic form (including singletons) can be obtained:

    >>> p.full_cyclic_form
    [[0, 1], [2], [3]]

    Any permutation can be factored into transpositions of pairs of elements:

    >>> Permutation([[1, 2], [3, 4, 5]]).transpositions()
    [(1, 2), (3, 5), (3, 4)]
    >>> Permutation.rmul(*[Permutation([ti], size=6) for ti in _]).cyclic_form
    [[1, 2], [3, 4, 5]]

    The number of permutations on a set of n elements is given by n! and is
    called the cardinality.

    >>> p.size
    4
    >>> p.cardinality
    24

    A given permutation has a rank among all the possible permutations of the
    same elements, but what that rank is depends on how the permutations are
    enumerated. (There are a number of different methods of doing so.) The
    lexicographic rank is given by the rank method and this rank is used to
    increment a permutation with addition/subtraction:

    >>> p.rank()
    6
    >>> p + 1
    Permutation([1, 0, 3, 2])
    >>> p.next_lex()
    Permutation([1, 0, 3, 2])
    >>> _.rank()
    7
    >>> p.unrank_lex(p.size, rank=7)
    Permutation([1, 0, 3, 2])

    The product of two permutations p and q is defined as their composition as
    functions, (p*q)(i) = q(p(i)) [6]_.

    >>> p = Permutation([1, 0, 2, 3])
    >>> q = Permutation([2, 3, 1, 0])
    >>> list(q*p)
    [2, 3, 0, 1]
    >>> list(p*q)
    [3, 2, 1, 0]
    >>> [q(p(i)) for i in range(p.size)]
    [3, 2, 1, 0]

    The permutation can be 'applied' to any list-like object, not only
    Permutations:

    >>> p(['zero', 'one', 'four', 'two'])
    ['one', 'zero', 'four', 'two']
    >>> p('zo42')
    ['o', 'z', '4', '2']

    If you have a list of arbitrary elements, the corresponding permutation
    can be found with the from_sequence method:

    >>> Permutation.from_sequence('SymPy')
    Permutation([1, 3, 2, 0, 4])

    Checking if a Permutation is contained in a Group
    =================================================

    Generally if you have a group of permutations G on n symbols, and
    you're checking if a permutation on less than n symbols is part
    of that group, the check will fail.

    Here is an example for n=5 and we check if the cycle
    (1,2,3) is in G:

    >>> from sympy import init_printing
    >>> init_printing(perm_cyclic=True, pretty_print=False)
    >>> from sympy.combinatorics import Cycle, Permutation
    >>> from sympy.combinatorics.perm_groups import PermutationGroup
    >>> G = PermutationGroup(Cycle(2, 3)(4, 5), Cycle(1, 2, 3, 4, 5))
    >>> p1 = Permutation(Cycle(2, 5, 3))
    >>> p2 = Permutation(Cycle(1, 2, 3))
    >>> a1 = Permutation(Cycle(1, 2, 3).list(6))
    >>> a2 = Permutation(Cycle(1, 2, 3)(5))
    >>> a3 = Permutation(Cycle(1, 2, 3),size=6)
    >>> for p in [p1,p2,a1,a2,a3]: p, G.contains(p)
    ((2 5 3), True)
    ((1 2 3), False)
    ((5)(1 2 3), True)
    ((5)(1 2 3), True)
    ((5)(1 2 3), True)

    The check for p2 above will fail.

    Checking if p1 is in G works because SymPy knows
    G is a group on 5 symbols, and p1 is also on 5 symbols
    (its largest element is 5).

    For ``a1``, the ``.list(6)`` call will extend the permutation to 5
    symbols, so the test will work as well. In the case of ``a2`` the
    permutation is being extended to 5 symbols by using a singleton,
    and in the case of ``a3`` it's extended through the constructor
    argument ``size=6``.

    There is another way to do this, which is to tell the ``contains``
    method that the number of symbols the group is on does not need to
    match perfectly the number of symbols for the permutation:

    >>> G.contains(p2,strict=False)
    True

    This can be via the ``strict`` argument to the ``contains`` method,
    and SymPy will try to extend the permutation on its own and then
    perform the containment check.

    See Also
    ========

    Cycle

    References
    ==========

    .. [1] Skiena, S. 'Permutations.' 1.1 in Implementing Discrete Mathematics
           Combinatorics and Graph Theory with Mathematica.  Reading, MA:
           Addison-Wesley, pp. 3-16, 1990.

    .. [2] Knuth, D. E. The Art of Computer Programming, Vol. 4: Combinatorial
           Algorithms, 1st ed. Reading, MA: Addison-Wesley, 2011.

    .. [3] Wendy Myrvold and Frank Ruskey. 2001. Ranking and unranking
           permutations in linear time. Inf. Process. Lett. 79, 6 (September 2001),
           281-284. DOI=10.1016/S0020-0190(01)00141-7

    .. [4] D. L. Kreher, D. R. Stinson 'Combinatorial Algorithms'
           CRC Press, 1999

    .. [5] Graham, R. L.; Knuth, D. E.; and Patashnik, O.
           Concrete Mathematics: A Foundation for Computer Science, 2nd ed.
           Reading, MA: Addison-Wesley, 1994.

    .. [6] https://en.wikipedia.org/w/index.php?oldid=499948155#Product_and_inverse

    .. [7] https://en.wikipedia.org/wiki/Lehmer_code

    TNrc   c          
         |t        |      }d}|s'| j                  t        t        |xs d                  S t	        |      dkD  r&| j                  t        | j                  |            S t	        |      dk(  r|d   }t        ||       r'|||j                  k(  r|S  | |j                  |      S t        |t
              r | j                  |j                  |            S t        |      s>||dz   |kD  rt        d|z        | j                  t        t        |dz                     S t        d |D              rd}nd}|st        d      t        |d         }|xr t        |d         }|r)|D cg c]  }|D cg c]  }t        |       c} }}}n|D cg c]  }t        |       }}t        |      }	t        |	      r|st        d	      t        |	      }	|s]|	t        t        t	        |	                  k7  rt        d
t        |	      z        |$|	r"t        |	      dz   |kD  rt        d|dz
  z        |r't               }|D ]  }
 ||
 }	 |j                         }nt        |      }|r;|t	        |      kD  r-|j!                  t        t        t	        |      |                   | j                  |      S c c}w c c}}w c c}w )a  
        Constructor for the Permutation object from a list or a
        list of lists in which all elements of the permutation may
        appear only once.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> from sympy import init_printing
        >>> init_printing(perm_cyclic=False, pretty_print=False)

        Permutations entered in array-form are left unaltered:

        >>> Permutation([0, 2, 1])
        Permutation([0, 2, 1])

        Permutations entered in cyclic form are converted to array form;
        singletons need not be entered, but can be entered to indicate the
        largest element:

        >>> Permutation([[4, 5, 6], [0, 1]])
        Permutation([1, 0, 2, 3, 5, 6, 4])
        >>> Permutation([[4, 5, 6], [0, 1], [19]])
        Permutation([1, 0, 2, 3, 5, 6, 4], size=20)

        All manipulation of permutations assumes that the smallest element
        is 0 (in keeping with 0-based indexing in Python) so if the 0 is
        missing when entering a permutation in array form, an error will be
        raised:

        >>> Permutation([2, 1])
        Traceback (most recent call last):
        ...
        ValueError: Integers 0 through 2 must be present.

        If a permutation is entered in cyclic form, it can be entered without
        singletons and the ``size`` specified so those values can be filled
        in, otherwise the array form will only extend to the maximum value
        in the cycles:

        >>> Permutation([[1, 4], [3, 5, 2]], size=10)
        Permutation([0, 4, 3, 5, 1, 2], size=10)
        >>> _.array_form
        [0, 4, 3, 5, 1, 2, 6, 7, 8, 9]
        Tr   r(   r   z size is too small when max is %sc              3   2   K   | ]  }t        |        y wrI   )r   )rK   rB   s     r   rL   z&Permutation.__new__.<locals>.<genexpr>  s     7r;r?7s   FzSPermutation argument must be a list of ints, a list of lists, Permutation or Cycle.zthere were repeated elements.z&Integers 0 through %s must be present.z max element should not exceed %s)int_af_newrE   r8   r*   rP   r   rc   
array_formr   r+   r   r   r   setrb   extend)clsrc   r   kwargsokr   is_cycler;   r   tempciaforms               r   __new__zPermutation.__new__  s   ^ t9D ;;tE$)!$4566Y];;ud|00677t9>QA!S!<4166>H1<<d33!U#{{166$<00q>#A$%G!%KLL{{4a!e#5667Q77B F G G
 DG}0KQ0156AQ'SV'6D6$()qCF)D) t}D>(<==4ys5T+,, !ID	"  DSY]T-A !Ctax!PQQ A rFFFHEJED3u:% LLeCJ567{{5!!I (6)s   7	K KKKKc                 T    t         |   |       }||_        t        |      |_        |S )a  A method to produce a Permutation object from a list;
        the list is bound to the _array_form attribute, so it must
        not be modified; this method is meant for internal use only;
        the list ``a`` is supposed to be generated as a temporary value
        in a method, so p = Perm._af_new(a) is the only object
        to hold a reference to ``a``::

        Examples
        ========

        >>> from sympy.combinatorics.permutations import Perm
        >>> from sympy import init_printing
        >>> init_printing(perm_cyclic=False, pretty_print=False)
        >>> a = [2, 1, 3, 0]
        >>> p = Perm._af_new(a)
        >>> p
        Permutation([2, 1, 3, 0])

        )superr   _array_formr*   _size)r   permp	__class__s      r   r   zPermutation._af_new  s*    * GOC d)r>   c                 8    | j                  | j                        S rI   )r   r   rV   s    r   r   zPermutation.copy  s    ~~doo..r>   c                     | j                   fS rI   r   rV   s    r   __getnewargs__zPermutation.__getnewargs__!  s    !!r>   c                 ,    t        | j                        S rI   )rj   r   rV   s    r   _hashable_contentzPermutation._hashable_content$  s     T__%%r>   c                      | j                   dd S )a  
        Return a copy of the attribute _array_form
        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([[2, 0], [3, 1]])
        >>> p.array_form
        [2, 3, 0, 1]
        >>> Permutation([[2, 0, 3, 1]]).array_form
        [3, 2, 0, 1]
        >>> Permutation([2, 0, 3, 1]).array_form
        [2, 0, 3, 1]
        >>> Permutation([[1, 2], [4, 5]]).array_form
        [0, 2, 1, 3, 5, 4]
        N)r   rV   s    r   r   zPermutation.array_form)  s    $ ""r>   c                 &   | s|t        d      | j                  }|s|| j                  kD  r0|j                  t	        t        | j                  |                   |S | j                  dz
  }|r#|d   |k7  r	 |S |j                          |dz  }|r#|S )a  Return the permutation as an explicit list, possibly
        trimming unmoved elements if size is less than the maximum
        element in the permutation; if this is desired, setting
        ``size=-1`` will guarantee such trimming.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation(2, 3)(4, 5)
        >>> p.list()
        [0, 1, 3, 2, 5, 4]
        >>> p.list(10)
        [0, 1, 3, 2, 5, 4, 6, 7, 8, 9]

        Passing a length too small will trim trailing, unchanged elements
        in the permutation:

        >>> Permutation(2, 4)(1, 2, 4).list(-1)
        [0, 2, 1]
        >>> Permutation(3).list(-1)
        []
        ra   r(   )r+   r   rc   r   rE   r8   pop)rR   rc   r\   r   s       r   rE   zPermutation.list=  s    0 =>>__dii		$uTYY567 	 IIM"v{ 	 FFHFA	 
 	r>   c                    | j                   t        | j                         S | j                  }dgt        |      z  }g }t	        t        |            D ]  }||   s	g }|j                  |       d||<   |}|||      r$||   }|j                  |       d||<   |||      r$t        |      dkD  s^|j                  |       |t        t        |            k(  rJ  |j                          |dd | _         |S )a  
        This is used to convert to the cyclic notation
        from the canonical notation. Singletons are omitted.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([0, 3, 1, 2])
        >>> p.cyclic_form
        [[1, 3, 2]]
        >>> Permutation([1, 0, 2, 4, 3, 5]).cyclic_form
        [[0, 1], [3, 4]]

        See Also
        ========

        array_form, full_cyclic_form
        NTFr(   )_cyclic_formrE   r   r*   r8   appendr   sort)rR   r   	uncheckedrt   r   cycler<   s          r   rt   zPermutation.cyclic_forme  s   * ())**__
FS_,	s:' 	8A|Q$	!
1."1ALLO#(IaL  
1. u:>&&u- D$7777	8 	'Nr>   c                     t        t        | j                              t        t        | j                              z
  }| j                  |D cg c]  }|g c}z   }|j                          |S c c}w )zReturn permutation in cyclic form including singletons.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> Permutation([0, 2, 1]).full_cyclic_form
        [[0], [1, 2]]
        )r   r8   rc   r   rt   r   )rR   needr   r\   s       r   full_cyclic_formzPermutation.full_cyclic_form  s\     5#$s743C3C+D'EEd 3! 33
		 !4s   
A.c                     | j                   S )a&  
        Returns the number of elements in the permutation.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> Permutation([[3, 2], [0, 1]]).size
        4

        See Also
        ========

        cardinality, length, order, rank
        )r   rV   s    r   rc   zPermutation.size  s    " zzr>   c                 t    | j                   }t        |      D cg c]  \  }}||   |k7  s| c}}S c c}}w )a1  Return the elements in permutation, P, for which P[i] != i.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([[3, 2], [0, 1], [4]])
        >>> p.array_form
        [1, 0, 3, 2, 4]
        >>> p.support()
        [0, 1, 2, 3]
        )r   r@   )rR   r   r   es       r   supportzPermutation.support  s3     OO'l8daadai888s   44c                     | j                         |z   | j                  z  }| j                  | j                  |      }||_        |S )a  Return permutation that is other higher in rank than self.

        The rank is the lexicographical rank, with the identity permutation
        having rank of 0.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> I = Permutation([0, 1, 2, 3])
        >>> a = Permutation([2, 1, 3, 0])
        >>> I + a.rank() == a
        True

        See Also
        ========

        __sub__, inversion_vector

        )rankcardinality
unrank_lexrc   _rank)rR   r[   r   r\   s       r   __add__zPermutation.__add__  s?    * 		e#t'7'77__TYY-	r>   c                 &    | j                  |       S )zzReturn the permutation that is other lower in rank than self.

        See Also
        ========

        __add__
        )r   )rR   r[   s     r   __sub__zPermutation.__sub__  s     ||UF##r>   c                  T    | d   }t        dt        |             D ]
  }| |   |z  } |S )a  
        Return product of Permutations [a, b, c, ...] as the Permutation whose
        ith value is a(b(c(i))).

        a, b, c, ... can be Permutation objects or tuples.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation

        >>> a, b = [1, 0, 2], [0, 2, 1]
        >>> a = Permutation(a); b = Permutation(b)
        >>> list(Permutation.rmul(a, b))
        [1, 2, 0]
        >>> [a(b(i)) for i in range(3)]
        [1, 2, 0]

        This handles the operands in reverse order compared to the ``*`` operator:

        >>> a = Permutation(a); b = Permutation(b)
        >>> list(a*b)
        [2, 0, 1]
        >>> [b(a(i)) for i in range(3)]
        [2, 0, 1]

        Notes
        =====

        All items in the sequence will be parsed by Permutation as
        necessary as long as the first item is a Permutation:

        >>> Permutation.rmul(a, [0, 2, 1]) == Permutation.rmul(a, b)
        True

        The reverse order of arguments will raise a TypeError.

        r   r(   )r8   r*   )r   r\   r   s      r   rmulzPermutation.rmul  s:    P !Wq#d)$ 	AaB		r>   c                 p    |D cg c]  }|j                    }}| j                  t        |       }|S c c}w )zo
        same as rmul, but the elements of args are Permutation objects
        which have _array_form
        )r   r   r,   )r   r   xr   r\   s        r   rmul_with_afzPermutation.rmul_with_af  s7     %))qQ]]))[[A'	 *s   3c                 z    t        | j                        }|j                  }| j                  t        ||            S )z>
        other*~self, self and other have _array_form
        )rC   r   r   r    rR   r[   r   r   s       r   mul_invzPermutation.mul_inv  s4     t''(||HQN++r>   c                 .    t        |       } ||      | z  S )z6This is needed to coerce other to Permutation in rmul.)type)rR   r[   r   s      r   __rmul__zPermutation.__rmul__&  s    4j5z$r>   c           
      V   ddl m}m} t        ||      r || |d      S | j                  }|j                  }|s|}nX|j                  t        t        t        |      t        |                         |D cg c]  }||   	 c}|t        |      d z   }| j                  |      S c c}w )a  
        Return the product a*b as a Permutation; the ith value is b(a(i)).

        Examples
        ========

        >>> from sympy.combinatorics.permutations import _af_rmul, Permutation

        >>> a, b = [1, 0, 2], [0, 2, 1]
        >>> a = Permutation(a); b = Permutation(b)
        >>> list(a*b)
        [2, 0, 1]
        >>> [b(a(i)) for i in range(3)]
        [2, 0, 1]

        This handles operands in reverse order compared to _af_rmul and rmul:

        >>> al = list(a); bl = list(b)
        >>> _af_rmul(al, bl)
        [1, 2, 0]
        >>> [al[bl[i]] for i in range(3)]
        [1, 2, 0]

        It is acceptable for the arrays to have different lengths; the shorter
        one will be padded to match the longer one:

        >>> from sympy import init_printing
        >>> init_printing(perm_cyclic=False, pretty_print=False)
        >>> b*Permutation([1, 0])
        Permutation([1, 2, 0])
        >>> Permutation([1, 0])*b
        Permutation([2, 0, 1])

        It is also acceptable to allow coercion to handle conversion of a
        single list to the left of a Permutation:

        >>> [0, 1]*a # no change: 2-element identity
        Permutation([1, 0, 2])
        >>> [[0, 1]]*a # exchange first two elements
        Permutation([0, 1, 2])

        You cannot use more than 1 cycle notation in a product of cycles
        since coercion can only handle one argument to the left. To handle
        multiple cycles it is convenient to use Cycle instead of Permutation:

        >>> [[1, 2]]*[[2, 3]]*Permutation([]) # doctest: +SKIP
        >>> from sympy.combinatorics.permutations import Cycle
        >>> Cycle(1, 2)(2, 3)
        (1 3 2)

        r   )PermutationGroupCoset-)dirN)
sympy.combinatorics.perm_groupsr   r   r   r   r   rE   r8   r*   r   )rR   r[   r   r   r   r   r   r   s           r   __mul__zPermutation.__mul__+  s    h 	Le-.u#..OODHHT%AA/01"#$QAaD$qQz1D||D!! %s   7B&c                 J    | j                   }|j                   }t        ||      S )a|  
        Checks if the elements are commuting.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> a = Permutation([1, 4, 3, 0, 2, 5])
        >>> b = Permutation([0, 1, 2, 3, 4, 5])
        >>> a.commutes_with(b)
        True
        >>> b = Permutation([2, 3, 5, 4, 1, 0])
        >>> a.commutes_with(b)
        False
        )r   rN   r   s       r   commutes_withzPermutation.commutes_withl  s%      OO A&&r>   c                     t        |t              rt        d      t        |      }| j	                  t        | j                  |            S )a  
        Routine for finding powers of a permutation.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> from sympy import init_printing
        >>> init_printing(perm_cyclic=False, pretty_print=False)
        >>> p = Permutation([2, 0, 3, 1])
        >>> p.order()
        4
        >>> p**4
        Permutation([0, 1, 2, 3])
        z1p**p is not defined; do you mean p^p (conjugate)?)r   rs   NotImplementedErrorr   r   rF   r   )rR   r:   s     r   __pow__zPermutation.__pow__  sC      a%%CE EF||GDOOQ788r>   c                 D    t        |      r | |      S t        d|z        )zReturn self(i) when ``i`` is an int.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation(1, 2, 9)
        >>> 2^p == p(2) == 9
        True
        z(i^p = p(i) when i is an integer, not %s.)r	   r   )rR   r   s     r   __rxor__zPermutation.__rxor__  s+     a=7N%:Q>@ @r>   c                    | j                   |j                   k7  rt        d      dg| j                   z  }|j                  }| j                  }t        | j                         D ]  }|||      |||   <    | j	                  |      S )a  Return the conjugate permutation ``~h*self*h` `.

        Explanation
        ===========

        If ``a`` and ``b`` are conjugates, ``a = h*b*~h`` and
        ``b = ~h*a*h`` and both have the same cycle structure.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation(1, 2, 9)
        >>> q = Permutation(6, 9, 8)
        >>> p*q != q*p
        True

        Calculate and check properties of the conjugate:

        >>> c = p^q
        >>> c == ~q*p*q and p == q*c*~q
        True

        The expression q^p^r is equivalent to q^(p*r):

        >>> r = Permutation(9)(4, 6, 8)
        >>> q^p^r == q^(p*r)
        True

        If the term to the left of the conjugate operator, i, is an integer
        then this is interpreted as selecting the ith element from the
        permutation to the right:

        >>> all(i^p == p(i) for i in range(p.size))
        True

        Note that the * operator as higher precedence than the ^ operator:

        >>> q^r*p^r == q^(r*p)^r == Permutation(9)(1, 6, 4)
        True

        Notes
        =====

        In Python the precedence rule is p^q^r = (p^q)^r which differs
        in general from p^(q^r)

        >>> q^p^r
        (9)(1 4 8)
        >>> q^(p^r)
        (9)(1 8 6)

        For a given r and p, both of the following are conjugates of p:
        ~r*p*r and r*p*~r. But these are not necessarily the same:

        >>> ~r*p*r == r*p*~r
        True

        >>> p = Permutation(1, 2, 9)(5, 6)
        >>> ~r*p*r == r*p*~r
        False

        The conjugate ~r*p*r was chosen so that ``p^q^r`` would be equivalent
        to ``p^(q*r)`` rather than ``p^(r*q)``. To obtain r*p*~r, pass ~r to
        this method:

        >>> p^~r == r*p*~r
        True
        'The permutations must be of equal size.N)rc   r+   r   r8   r   )rR   hr   r   r   s        r   __xor__zPermutation.__xor__  s    N 99FGGF499MMtyy! 	A!gAadG	||Ar>   c                     | j                   }g }|D ][  }t        |      }|dk(  r|j                  t        |             .|dkD  s4|d   }||dz
  dd   D ]  }|j                  ||f        ] |S )a  
        Return the permutation decomposed into a list of transpositions.

        Explanation
        ===========

        It is always possible to express a permutation as the product of
        transpositions, see [1]

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([[1, 2, 3], [0, 4, 5, 6, 7]])
        >>> t = p.transpositions()
        >>> t
        [(0, 7), (0, 6), (0, 5), (0, 4), (1, 3), (1, 2)]
        >>> print(''.join(str(c) for c in t))
        (0, 7)(0, 6)(0, 5)(0, 4)(1, 3)(1, 2)
        >>> Permutation.rmul(*[Permutation([ti], size=p.size) for ti in t]) == p
        True

        References
        ==========

        .. [1] https://en.wikipedia.org/wiki/Transposition_%28mathematics%29#Properties

        r)   r   r(   r   )rt   r*   r   rj   )rR   r   resr   nxfirstys          r   transpositionszPermutation.transpositions  s    :  	+AQBQw

58$a!26!B; +AJJqz*+	+ 
r>   c                     t        t        |t        t        t        |                              }r|j	                  fd       n|j	                          t        |D cg c]  }|d   	 c}       S c c}w )a  Return the permutation needed to obtain ``i`` from the sorted
        elements of ``i``. If custom sorting is desired, a key can be given.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation

        >>> Permutation.from_sequence('SymPy')
        (4)(0 1 3)
        >>> _(sorted("SymPy"))
        ['S', 'y', 'm', 'P', 'y']
        >>> Permutation.from_sequence('SymPy', key=lambda x: x.lower())
        (4)(0 2)(1 3)
        c                      | d         S )Nr   r   )r   keys    r   <lambda>z+Permutation.from_sequence.<locals>.<lambda>3  s    #ad) r>   )r   r(   )rE   rY   r8   r*   r   rs   )rR   r   r   ics     ` r   from_sequencezPermutation.from_sequence   s^    " #aeCFm,-.GG+G,GGI2.aQqT.///.s   #A7c                 J    | j                  t        | j                              S )a  
        Return the inverse of the permutation.

        A permutation multiplied by its inverse is the identity permutation.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> from sympy import init_printing
        >>> init_printing(perm_cyclic=False, pretty_print=False)
        >>> p = Permutation([[2, 0], [3, 1]])
        >>> ~p
        Permutation([2, 3, 0, 1])
        >>> _ == p**-1
        True
        >>> p*~p == ~p*p == Permutation([0, 1, 2, 3])
        True
        )r   rC   r   rV   s    r   
__invert__zPermutation.__invert__8  s    ( ||Jt'7'7899r>   c              #   8   K   | j                   E d{    y7 w)zYield elements from array form.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> list(Permutation(range(3)))
        [0, 1, 2]
        Nr   rV   s    r   rW   zPermutation.__iter__N  s      ??""s   c                     t        |       S rI   r   rV   s    r   ry   zPermutation.__repr__Z  r   r>   c                    t        |      dk(  r|d   }t        |t              sVt        |      }|dk  s|| j                  kD  r(t        dj                  || j                  dz
              | j                  |   S t        |      | j                  k7  r%t        dj                  || j                              | j                  D cg c]  }||   	 c}S | t        t        | | j                        z  S c c}w )a+  
        Allows applying a permutation instance as a bijective function.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([[2, 0], [3, 1]])
        >>> p.array_form
        [2, 3, 0, 1]
        >>> [p(i) for i in range(4)]
        [2, 3, 0, 1]

        If an array is given then the permutation selects the items
        from the array (i.e. the permutation is applied to the array):

        >>> from sympy.abc import x
        >>> p([x, 1, 0, x**2])
        [0, x**2, x, 1]
        r(   r   ({} should be an integer between 0 and {}z{} should have the length {}.r   )
r*   r   r   r   rc   	TypeErrorformatr   rs   rP   )rR   r   r<   s      r   r_   zPermutation.__call__]  s    0 q6Q;!Aa*1Iq5A		M#B499Q;/1 1 ''**1v"3::1diiHJ J"&"2"23QAaD33Kq			::: 4s   C4c                 ,    t        | j                        S )a;  
        Returns all the elements of a permutation

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> Permutation([0, 1, 2, 3, 4, 5]).atoms()
        {0, 1, 2, 3, 4, 5}
        >>> Permutation([[0, 1], [2, 3], [4, 5]]).atoms()
        {0, 1, 2, 3, 4, 5}
        )r   r   rV   s    r   atomszPermutation.atoms  s     4??##r>   c                 <   t        |      }|j                  du rt        dj                  |            | j                  }|dk  dk(  s||k\  dk(  rt        dj                  ||dz
              |j
                  rt        | j                  |         S t        | |      S )a:  Apply the permutation to an expression.

        Parameters
        ==========

        i : Expr
            It should be an integer between $0$ and $n-1$ where $n$
            is the size of the permutation.

            If it is a symbol or a symbolic expression that can
            have integer values, an ``AppliedPermutation`` object
            will be returned which can represent an unevaluated
            function.

        Notes
        =====

        Any permutation can be defined as a bijective function
        $\sigma : \{ 0, 1, \dots, n-1 \} \rightarrow \{ 0, 1, \dots, n-1 \}$
        where $n$ denotes the size of the permutation.

        The definition may even be extended for any set with distinctive
        elements, such that the permutation can even be applied for
        real numbers or such, however, it is not implemented for now for
        computational reasons and the integrity with the group theory
        module.

        This function is similar to the ``__call__`` magic, however,
        ``__call__`` magic already has some other applications like
        permuting an array or attaching new cycles, which would
        not always be mathematically consistent.

        This also guarantees that the return type is a SymPy integer,
        which guarantees the safety to use assumptions.
        Fz{} should be an integer.r   Tr   r(   )	r   
is_integerr   r   rc   
is_Integerr
   r   AppliedPermutation)rR   r   r:   s      r   applyzPermutation.apply  s    H QK<<5 %&@&G&G&JKKIIEd?qAv$.%:AA!QqSIK K <<4++A.//!$**r>   c                 v   | j                   dd }t        |      }|dz
  }||dz      ||   k  r|dz  }||dz      ||   k  r|dk(  ry|dz
  }||   ||   k  r|dz  }||   ||   k  r||   ||   c||<   ||<   |dz  }|dz
  }||k  r!||   ||   c||<   ||<   |dz  }|dz  }||k  r!| j                  |      S )a  
        Returns the next permutation in lexicographical order.
        If self is the last permutation in lexicographical order
        it returns None.
        See [4] section 2.4.


        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([2, 3, 1, 0])
        >>> p = Permutation([2, 3, 1, 0]); p.rank()
        17
        >>> p = p.next_lex(); p.rank()
        18

        See Also
        ========

        rank, unrank_lex
        Nr)   r(   r   )r   r*   r   )rR   r   r:   r   r<   s        r   next_lexzPermutation.next_lex  s   . q!IE1q5kDG#FA 1q5kDG#7AAq'DG#Q q'DG##AwQDGT!WFAAAa%#'7DG QaQQ a% ||D!!r>   c                     fdt        t        |            }t        |      }|t        |      z  } |||       | j	                  |      S )a  
        This is a linear time unranking algorithm that does not
        respect lexicographic order [3].

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> from sympy import init_printing
        >>> init_printing(perm_cyclic=False, pretty_print=False)
        >>> Permutation.unrank_nonlex(4, 5)
        Permutation([2, 0, 3, 1])
        >>> Permutation.unrank_nonlex(4, -1)
        Permutation([0, 1, 2, 3])

        See Also
        ========

        next_nonlex, rank_nonlex
        c                 l    | dkD  r.||| z     || dz
     c|| dz
  <   ||| z  <    | dz
  || z  |       y y r   r   )r:   rr   _unrank1s      r   r  z+Permutation.unrank_nonlex.<locals>._unrank1  sO    1u%&q1uXqQx"!a%!AE(Q1a( r>   )rE   r8   r   r   r   )rR   r:   r  id_permr  s       @r   unrank_nonlexzPermutation.unrank_nonlex  sH    ,	)
 uQx.FQKAw||G$$r>   c                 z    fd||  j                   }|sy| j                   dd } t        |      ||      }|S )ae  
        This is a linear time ranking algorithm that does not
        enforce lexicographic order [3].


        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([0, 1, 2, 3])
        >>> p.rank_nonlex()
        23

        See Also
        ========

        next_nonlex, unrank_nonlex
        c                     | dk(  ry|| dz
     }|| dz
     }||   |c|| dz
  <   ||<   ||   |c|| dz
  <   ||<   ||  | dz
  ||      z  z   S )Nr(   r   r   )r:   r   inv_permrx   t_rank1s        r   r  z'Permutation.rank_nonlex.<locals>._rank1%  s|    AvQUAQA#'7A DQKa+3A;(HQUOXa[qAtX6666r>   Nr   )r   r*   )rR   r
  r   r  r  s       @r   rank_nonlexzPermutation.rank_nonlex  sH    &	7 ))Hq!3t9dH-r>   c                     | j                         }|t        | j                        dz
  k(  ry| j                  | j                  |dz         S )aJ  
        Returns the next permutation in nonlex order [3].
        If self is the last permutation in this order it returns None.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> from sympy import init_printing
        >>> init_printing(perm_cyclic=False, pretty_print=False)
        >>> p = Permutation([2, 0, 3, 1]); p.rank_nonlex()
        5
        >>> p = p.next_nonlex(); p
        Permutation([3, 0, 1, 2])
        >>> p.rank_nonlex()
        6

        See Also
        ========

        rank_nonlex, unrank_nonlex
        r(   N)r  r   rc   r  )rR   r  s     r   next_nonlexzPermutation.next_nonlex6  sE    . TYY!##!!$))QU33r>   c                 `   | j                   | j                   S d}| j                  dd }| j                  dz
  }|dz   }t        t	        |            }t        |dz
        D ]D  }|||   |z  z  }t        |dz   |      D ]  }||   ||   kD  s||xx   dz  cc<    ||z  }|dz  }F || _         |S )a  
        Returns the lexicographic rank of the permutation.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([0, 1, 2, 3])
        >>> p.rank()
        0
        >>> p = Permutation([3, 2, 1, 0])
        >>> p.rank()
        23

        See Also
        ========

        next_lex, unrank_lex, cardinality, length, order, size
        Nr   r(   )r   r   rc   r   r   r8   )rR   r   rhor:   rc   psizer<   r   s           r   r   zPermutation.rankR  s    ( ::!::ooa IIM1uDGtax 	ACF5L D1q5$'  q6CF?FaKF  aKEFA	 
r>   c                 >    t        t        | j                              S )a3  
        Returns the number of all possible permutations.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([0, 1, 2, 3])
        >>> p.cardinality
        24

        See Also
        ========

        length, order, rank, size
        )r   r   rc   rV   s    r   r   zPermutation.cardinalityw  s    $ 4		?##r>   c                 |    | j                   | j                  | j                  z
  dz  S t        | j                        S )aP  
        Computes the parity of a permutation.

        Explanation
        ===========

        The parity of a permutation reflects the parity of the
        number of inversions in the permutation, i.e., the
        number of pairs of x and y such that ``x > y`` but ``p[x] < p[y]``.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([0, 1, 2, 3])
        >>> p.parity()
        0
        >>> p = Permutation([3, 2, 0, 1])
        >>> p.parity()
        1

        See Also
        ========

        _af_parity
        r)   )r   rc   rw   r=   r   rV   s    r   parityzPermutation.parity  s7    6 (II+q00$//**r>   c                     | j                    S )a[  
        Checks if a permutation is even.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([0, 1, 2, 3])
        >>> p.is_even
        True
        >>> p = Permutation([3, 2, 1, 0])
        >>> p.is_even
        True

        See Also
        ========

        is_odd
        )is_oddrV   s    r   is_evenzPermutation.is_even  s    * ;;r>   c                 :    t        | j                         dz        S )aZ  
        Checks if a permutation is odd.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([0, 1, 2, 3])
        >>> p.is_odd
        False
        >>> p = Permutation([3, 2, 0, 1])
        >>> p.is_odd
        True

        See Also
        ========

        is_even
        r)   )boolr  rV   s    r   r  zPermutation.is_odd  s    * DKKMA%&&r>   c                      | j                   dk(  S )a  
        Checks to see if the permutation contains only one number and is
        thus the only possible permutation of this set of numbers

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> Permutation([0]).is_Singleton
        True
        >>> Permutation([0, 1]).is_Singleton
        False

        See Also
        ========

        is_Empty
        r(   r   rV   s    r   is_SingletonzPermutation.is_Singleton  s    ( yyA~r>   c                      | j                   dk(  S )aI  
        Checks to see if the permutation is a set with zero elements

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> Permutation([]).is_Empty
        True
        >>> Permutation([0]).is_Empty
        False

        See Also
        ========

        is_Singleton
        r   r   rV   s    r   is_EmptyzPermutation.is_Empty  s    & yyA~r>   c                     | j                   S rI   )is_IdentityrV   s    r   is_identityzPermutation.is_identity  s    r>   c                 t    | j                    xs' t        fdt        | j                        D              S )a  
        Returns True if the Permutation is an identity permutation.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([])
        >>> p.is_Identity
        True
        >>> p = Permutation([[0], [1], [2]])
        >>> p.is_Identity
        True
        >>> p = Permutation([0, 1, 2])
        >>> p.is_Identity
        True
        >>> p = Permutation([0, 2, 1])
        >>> p.is_Identity
        False

        See Also
        ========

        order
        c              3   .   K   | ]  }||   k(    y wrI   r   )rK   r   afs     r   rL   z*Permutation.is_Identity.<locals>.<genexpr>$  s     BAQ"Q%ZBs   )r   allr8   rc   )rR   r$  s    @r   r   zPermutation.is_Identity  s/    6 __vBBtyy1ABBBr>   c                     | j                   }t        t        |      dz
        D cg c]  }||   ||dz      k  s| }}|S c c}w )al  
        Returns the positions of ascents in a permutation, ie, the location
        where p[i] < p[i+1]

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([4, 0, 1, 3, 2])
        >>> p.ascents()
        [1, 2]

        See Also
        ========

        descents, inversions, min, max
        r(   r   r8   r*   rR   r   r   poss       r   ascentszPermutation.ascents&  J    $ OOA
+?QqtaAhq??
 @
   AAc                     | j                   }t        t        |      dz
        D cg c]  }||   ||dz      kD  s| }}|S c c}w )am  
        Returns the positions of descents in a permutation, ie, the location
        where p[i] > p[i+1]

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([4, 0, 1, 3, 2])
        >>> p.descents()
        [0, 3]

        See Also
        ========

        ascents, inversions, min, max
        r(   r'  r(  s       r   descentszPermutation.descents<  r+  r,  returnc                 V    | j                   }|syt        d t        |      D              S )a5  
        The maximum element moved by the permutation.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([1, 0, 2, 3, 4])
        >>> p.max()
        1

        See Also
        ========

        min, descents, ascents, inversions
        r   c              3   2   K   | ]  \  }}||k7  s|  y wrI   r   rK   r   _as      r   rL   z"Permutation.max.<locals>.<genexpr>f       ;%!R272;   )r   rb   r@   rR   r   s     r   rb   zPermutation.maxR  (    " OO;9Q<;;;r>   c                 V    | j                   }|syt        d t        |      D              S )a5  
        The minimum element moved by the permutation.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([0, 1, 4, 3, 2])
        >>> p.min()
        2

        See Also
        ========

        max, descents, ascents, inversions
        r   c              3   2   K   | ]  \  }}||k7  s|  y wrI   r   r2  s      r   rL   z"Permutation.min.<locals>.<genexpr>|  r4  r5  )r   minr@   r6  s     r   r:  zPermutation.minh  r7  r>   c                 l   d}| j                   }t        |      }|dk  r2t        |dz
        D ]  }||   }||dz   d D ]  }||kD  s	|dz  } ! |S d}d}|dd }	|dd }
||k  rPd}||z   |k  r;||dz  z   dz
  }||k\  r|dz
  }|t        |	|
|||z   |      z  }||dz  z   }||z   |k  r;|dz  }||k  rP|S )aE  
        Computes the number of inversions of a permutation.

        Explanation
        ===========

        An inversion is where i > j but p[i] < p[j].

        For small length of p, it iterates over all i and j
        values and calculates the number of inversions.
        For large length of p, it uses a variation of merge
        sort to calculate the number of inversions.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([0, 1, 2, 3, 4, 5])
        >>> p.inversions()
        0
        >>> Permutation([3, 2, 1, 0]).inversions()
        6

        See Also
        ========

        descents, ascents, min, max

        References
        ==========

        .. [1] https://www.cp.eng.chula.ac.th/~prabhas//teaching/algo/algo2008/count-inv.htm

        r      r(   Nr)   )r   r*   r8   _merge)rR   
inversionsr   r:   r   r   r;   r]   rightarrr   s              r   r>  zPermutation.inversions~  s   F 
OOFs71q5\ (aD1q56 (A1u"a
((&  AEA$CQ4Da%!eaiAIMEz !A&dAq1ue"DDJAE	A !eai E a% r>   c           	      L   | j                   }|j                   }t        |      }t        |      |k7  rt        d      dg|z  }t        |      D ]
  }||||   <    dg|z  }t        |      D ]
  }||||   <    | j	                  |D cg c]  }||||          c}      S c c}w )a%  Return the commutator of ``self`` and ``x``: ``~x*~self*x*self``

        If f and g are part of a group, G, then the commutator of f and g
        is the group identity iff f and g commute, i.e. fg == gf.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> from sympy import init_printing
        >>> init_printing(perm_cyclic=False, pretty_print=False)
        >>> p = Permutation([0, 2, 3, 1])
        >>> x = Permutation([2, 0, 3, 1])
        >>> c = p.commutator(x); c
        Permutation([2, 1, 3, 0])
        >>> c == ~x*~p*x*p
        True

        >>> I = Permutation(3)
        >>> p = [I + i for i in range(6)]
        >>> for i in range(len(p)):
        ...     for j in range(len(p)):
        ...         c = p[i].commutator(p[j])
        ...         if p[i]*p[j] == p[j]*p[i]:
        ...             assert c == I
        ...         else:
        ...             assert c != I
        ...

        References
        ==========

        .. [1] https://en.wikipedia.org/wiki/Commutator
        r   N)r   r*   r+   r8   r   )rR   r   r   r   r:   invar   invbs           r   
commutatorzPermutation.commutator  s    H OOLLFq6Q;FGGvaxq 	AD1J	vaxq 	AD1J	||D9qQqaz]9::9s   B!c                     | j                   ryy)a:  
        Gives the signature of the permutation needed to place the
        elements of the permutation in canonical order.

        The signature is calculated as (-1)^<number of inversions>

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([0, 1, 2])
        >>> p.inversions()
        0
        >>> p.signature()
        1
        >>> q = Permutation([0,2,1])
        >>> q.inversions()
        1
        >>> q.signature()
        -1

        See Also
        ========

        inversions
        r(   r   )r  rV   s    r   	signaturezPermutation.signature  s    6 <<r>   c           	      p    t        t        | j                  D cg c]  }t        |       c}d      S c c}w )aP  
        Computes the order of a permutation.

        When the permutation is raised to the power of its
        order it equals the identity permutation.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> from sympy import init_printing
        >>> init_printing(perm_cyclic=False, pretty_print=False)
        >>> p = Permutation([3, 1, 5, 2, 4, 0])
        >>> p.order()
        4
        >>> (p**(p.order()))
        Permutation([], size=6)

        See Also
        ========

        identity, cardinality, length, rank, size
        r(   )r   r   rt   r*   )rR   r   s     r   orderzPermutation.order
	  s+    2 cD4D4DE5CJEqIIEs   3
c                 4    t        | j                               S )ax  
        Returns the number of integers moved by a permutation.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> Permutation([0, 3, 2, 1]).length()
        2
        >>> Permutation([[0, 1], [2, 3]]).length()
        4

        See Also
        ========

        min, max, support, cardinality, order, rank, size
        )r*   r   rV   s    r   lengthzPermutation.length%	  s    & 4<<>""r>   c                    | j                   r| j                   }t        |      S t        t              }| j                  }| j                  D ]&  }|t        |      xx   dz  cc<   |t        |      z  }( |r||d<   || _         t        |      S )ah  Return the cycle structure of the permutation as a dictionary
        indicating the multiplicity of each cycle length.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> Permutation(3).cycle_structure
        {1: 4}
        >>> Permutation(0, 4, 3)(1, 2)(5, 6).cycle_structure
        {2: 2, 3: 1}
        r(   )_cycle_structurer   r   rc   rt   r*   dict)rR   r\   
singletonsr;   s       r   cycle_structurezPermutation.cycle_structure:	  s       &&B Bx S!BJ%% %3q6
a
c!f$
% "1$&D!Bxr>   c                 ,    t        | j                        S )a  
        Returns the number of cycles contained in the permutation
        (including singletons).

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> Permutation([0, 1, 2]).cycles
        3
        >>> Permutation([0, 1, 2]).full_cyclic_form
        [[0], [1], [2]]
        >>> Permutation(0, 1)(2, 3).cycles
        2

        See Also
        ========
        sympy.functions.combinatorial.numbers.stirling
        )r*   r   rV   s    r   rw   zPermutation.cyclesU	  s    * 4(())r>   c                 n    | j                   t        fdt        t              dz
        D              S )aP  
        Returns the index of a permutation.

        The index of a permutation is the sum of all subscripts j such
        that p[j] is greater than p[j+1].

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([3, 0, 2, 1, 4])
        >>> p.index()
        2
        c              3   @   K   | ]  }|   |d z      kD  s|  yw)r(   Nr   )rK   r<   r   s     r   rL   z$Permutation.index.<locals>.<genexpr>}	  s#     C1Q4!AE(?1Cs   r(   )r   sumr8   r*   r6  s    @r   indexzPermutation.indexl	  s,     OOCeCFQJ/CCCr>   c                 ,    t        | j                        S )a  
        Returns the runs of a permutation.

        An ascending sequence in a permutation is called a run [5].


        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([2, 5, 7, 3, 6, 0, 1, 4, 8])
        >>> p.runs()
        [[2, 5, 7], [3, 6], [0, 1, 4, 8]]
        >>> q = Permutation([1,3,2,0])
        >>> q.runs()
        [[1, 3], [2], [0]]
        )r   r   rV   s    r   r   zPermutation.runs	  s    $ DOO$$r>   c                     | j                   }t        |      }dg|dz
  z  }t        |dz
        D ].  }d}t        |dz   |      D ]  }||   ||   k  s|dz  } |||<   0 |S )a|  Return the inversion vector of the permutation.

        The inversion vector consists of elements whose value
        indicates the number of elements in the permutation
        that are lesser than it and lie on its right hand side.

        The inversion vector is the same as the Lehmer encoding of a
        permutation.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([4, 8, 0, 7, 1, 5, 3, 6, 2])
        >>> p.inversion_vector()
        [4, 7, 0, 5, 0, 2, 1, 1]
        >>> p = Permutation([3, 2, 1, 0])
        >>> p.inversion_vector()
        [3, 2, 1]

        The inversion vector increases lexicographically with the rank
        of the permutation, the -ith element cycling through 0..i.

        >>> p = Permutation(2)
        >>> while p:
        ...     print('%s %s %s' % (p, p.inversion_vector(), p.rank()))
        ...     p = p.next_lex()
        (2) [0, 0] 0
        (1 2) [0, 1] 1
        (2)(0 1) [1, 0] 2
        (0 1 2) [1, 1] 3
        (0 2 1) [2, 0] 4
        (0 2) [2, 1] 5

        See Also
        ========

        from_inversion_vector
        r   r(   )r   r*   r8   )rR   self_array_formr:   inversion_vectorr   valr<   s          r   rX  zPermutation.inversion_vector	  s    P // 3!a%=q1u 	&AC1q5!_ "1%(::1HC #&Q	&  r>   c                 N   | j                   g k(  s| j                  ry| j                   ddgk(  ry| j                   }| j                  }d}t        d|      D ]M  }d}d}||   |k7  r||   |k  r|dz  }|dz  }||   |k7  r|dz   }|dz  dk(  r||z  |z   |z
  }C||z  |z   dz
  }O |S )a  
        Returns the Trotter Johnson rank, which we get from the minimal
        change algorithm. See [4] section 2.4.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([0, 1, 2, 3])
        >>> p.rank_trotterjohnson()
        0
        >>> p = Permutation([0, 2, 1, 3])
        >>> p.rank_trotterjohnson()
        7

        See Also
        ========

        unrank_trotterjohnson, next_trotterjohnson
        r   r(   r)   )r   r   rc   r8   )rR   r   r:   r   r<   r]   r   j1s           r   rank_trotterjohnsonzPermutation.rank_trotterjohnson	  s    * ??b D$4$4??q!f$IIq! 	'AAAq'Q,7Q;FAQ q'Q, QBax1}$w|a'$w{Q	' r>   c                 n   dg|z  }d}t        |      }d}t        d|dz         D ]~  }||z  }||z  |z  }|||z  z
  }	|dz  dk(  r5t        |dz
  ||	z
  dz
  d      D ]  }
||
dz
     ||
<    |dz
  |||	z
  dz
  <   n(t        |dz
  |	d      D ]  }
||
dz
     ||
<    |dz
  ||	<   |} | j                  |      S )a  
        Trotter Johnson permutation unranking. See [4] section 2.4.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> from sympy import init_printing
        >>> init_printing(perm_cyclic=False, pretty_print=False)
        >>> Permutation.unrank_trotterjohnson(5, 10)
        Permutation([0, 3, 1, 2, 4])

        See Also
        ========

        rank_trotterjohnson, next_trotterjohnson
        r   r(   r)   r   )r   r8   r   )r   rc   r   r   r2r:   pjr<   r1r]   r   s              r   unrank_trotterjohnsonz!Permutation.unrank_trotterjohnson	  s   & s4xJq$(# 	A!GB)!BQrT	AAv{q1ua!eai4 *A"1q5kDG*"#a%QUQYq1ua, *A"1q5kDG*a%QB	 {{4  r>   c                    | j                   dd }t        |      }d}|dd }d}|dz
  }|dkD  r|s|j                  |      }t        ||      D ]  }||dz      ||<    t	        |d|       }	|	dk(  r1||k(  r|dz  }n[|||z   dz      |||z      c|||z   <   |||z   dz   <   d}n5|dk(  r|dz  }|dz  }n%|||z   dz
     |||z      c|||z   <   |||z   dz
  <   d}|dkD  r|s|dk(  ry| j                  |      S )aO  
        Returns the next permutation in Trotter-Johnson order.
        If self is the last permutation it returns None.
        See [4] section 2.4. If it is desired to generate all such
        permutations, they can be generated in order more quickly
        with the ``generate_bell`` function.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> from sympy import init_printing
        >>> init_printing(perm_cyclic=False, pretty_print=False)
        >>> p = Permutation([3, 0, 2, 1])
        >>> p.rank_trotterjohnson()
        4
        >>> p = p.next_trotterjohnson(); p
        Permutation([0, 3, 2, 1])
        >>> p.rank_trotterjohnson()
        5

        See Also
        ========

        rank_trotterjohnson, unrank_trotterjohnson, sympy.utilities.iterables.generate_bell
        Nr   Fr(   T)r   r*   rT  r8   r=   r   )
rR   r9   r:   str  doner.   dr   pars
             r   next_trotterjohnsonzPermutation.next_trotterjohnson
  sK   6 __QGeaC!eD		!A1a[ $QUA$S!W%Cax6FA13BFQJBF.BrAvJ26A:D6FA!GB13BFQJBF.BrAvJ26A:D# !eD$ 6||Br>   c                     t        | j                        }| j                  }t        |j                        D ]-  }t        |dz   |j
                        D ]  }d|||   ||   f<    / |S )a  
        Gets the precedence matrix. This is used for computing the
        distance between two permutations.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> from sympy import init_printing
        >>> init_printing(perm_cyclic=False, pretty_print=False)
        >>> p = Permutation.josephus(3, 6, 1)
        >>> p
        Permutation([2, 5, 3, 1, 4, 0])
        >>> p.get_precedence_matrix()
        Matrix([
        [0, 0, 0, 0, 0, 0],
        [1, 0, 0, 0, 1, 0],
        [1, 1, 0, 1, 1, 1],
        [1, 1, 0, 0, 1, 0],
        [1, 0, 0, 0, 0, 0],
        [1, 1, 0, 1, 1, 0]])

        See Also
        ========

        get_precedence_distance, get_adjacency_matrix, get_adjacency_distance
        r(   )r   rc   r   r8   rowscols)rR   r.   r   r   r<   s        r   get_precedence_matrixz!Permutation.get_precedence_matrixN
  sn    8 $))qvv 	(A1q5!&&) (&'$q'47"#(	( r>   c                 z   | j                   |j                   k7  rt        d      | j                         }|j                         }d}t        | j                         D ]:  }t        | j                         D ]   }||k(  r	|||f   |||f   z  dk(  s|dz  }" < | j                   | j                   dz
  z  dz  |z
  }|S )a  
        Computes the precedence distance between two permutations.

        Explanation
        ===========

        Suppose p and p' represent n jobs. The precedence metric
        counts the number of times a job j is preceded by job i
        in both p and p'. This metric is commutative.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([2, 0, 4, 3, 1])
        >>> q = Permutation([3, 1, 2, 4, 0])
        >>> p.get_precedence_distance(q)
        7
        >>> q.get_precedence_distance(p)
        7

        See Also
        ========

        get_precedence_matrix, get_adjacency_matrix, get_adjacency_distance
        r   r   r(   r)   )rc   r+   rk  r8   )rR   r[   self_prec_matother_prec_matn_precr   r<   re  s           r   get_precedence_distancez#Permutation.get_precedence_distanceq
  s    6 99

"FGG224446tyy! 	 A499%  6 A&1)==BaKF	 	  IIQ'*V3r>   c                     t        | j                        }| j                  }t        | j                  dz
        D ]  }d|||   ||dz      f<    |S )a  
        Computes the adjacency matrix of a permutation.

        Explanation
        ===========

        If job i is adjacent to job j in a permutation p
        then we set m[i, j] = 1 where m is the adjacency
        matrix of p.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation.josephus(3, 6, 1)
        >>> p.get_adjacency_matrix()
        Matrix([
        [0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 1, 0],
        [0, 0, 0, 0, 0, 1],
        [0, 1, 0, 0, 0, 0],
        [1, 0, 0, 0, 0, 0],
        [0, 0, 0, 1, 0, 0]])
        >>> q = Permutation([0, 1, 2, 3])
        >>> q.get_adjacency_matrix()
        Matrix([
        [0, 1, 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, 1],
        [0, 0, 0, 0]])

        See Also
        ========

        get_precedence_matrix, get_precedence_distance, get_adjacency_distance
        r(   )r   rc   r   r8   )rR   r.   r   r   s       r   get_adjacency_matrixz Permutation.get_adjacency_matrix
  sX    J $))tyy1}% 	(A&'Ad1gtAE{"#	(r>   c                 Z   | j                   |j                   k7  rt        d      | j                         }|j                         }d}t        | j                         D ]:  }t        | j                         D ]   }||k(  r	|||f   |||f   z  dk(  s|dz  }" < | j                   |z
  dz
  }|S )as  
        Computes the adjacency distance between two permutations.

        Explanation
        ===========

        This metric counts the number of times a pair i,j of jobs is
        adjacent in both p and p'. If n_adj is this quantity then
        the adjacency distance is n - n_adj - 1 [1]

        [1] Reeves, Colin R. Landscapes, Operators and Heuristic search, Annals
        of Operational Research, 86, pp 473-490. (1999)


        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([0, 3, 1, 2, 4])
        >>> q = Permutation.josephus(4, 5, 2)
        >>> p.get_adjacency_distance(q)
        3
        >>> r = Permutation([0, 2, 1, 4, 3])
        >>> p.get_adjacency_distance(r)
        4

        See Also
        ========

        get_precedence_matrix, get_precedence_distance, get_adjacency_matrix
        *The permutations must be of the same size.r   r(   )rc   r+   rr  r8   )rR   r[   self_adj_matother_adj_matn_adjr   r<   re  s           r   get_adjacency_distancez"Permutation.get_adjacency_distance
  s    @ 99

"IJJ002224tyy! 	A499% 61%ad(;;q@QJE		 II!r>   c                     | j                   |j                   t              t              k7  rt        d      t        fdt	        t                    D              S )a  
        Computes the positional distance between two permutations.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> p = Permutation([0, 3, 1, 2, 4])
        >>> q = Permutation.josephus(4, 5, 2)
        >>> r = Permutation([3, 1, 4, 0, 2])
        >>> p.get_positional_distance(q)
        12
        >>> p.get_positional_distance(r)
        12

        See Also
        ========

        get_precedence_distance, get_adjacency_distance
        rt  c              3   F   K   | ]  }t        |   |   z
          y wrI   )absrJ   s     r   rL   z6Permutation.get_positional_distance.<locals>.<genexpr>  s"     ;3qtad{#;s   !)r   r*   r+   rS  r8   r   s     @@r   get_positional_distancez#Permutation.get_positional_distance
  sN    * OOq6SVIJJ;U3q6];;;r>   c                    ddl m} |dz  } |t        t        |                  }g }t	        |      t        |d      kD  rgt        |      D ]!  }|j                  |j                                # |j                  |j                                t	        |      t        |d      kD  rg|j                  t        |              | |      S )a  Return as a permutation the shuffling of range(n) using the Josephus
        scheme in which every m-th item is selected until all have been chosen.
        The returned permutation has elements listed by the order in which they
        were selected.

        The parameter ``s`` stops the selection process when there are ``s``
        items remaining and these are selected by continuing the selection,
        counting by 1 rather than by ``m``.

        Consider selecting every 3rd item from 6 until only 2 remain::

            choices    chosen
            ========   ======
              012345
              01 345   2
              01 34    25
              01  4    253
              0   4    2531
              0        25314
                       253140

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> Permutation.josephus(3, 6, 2).array_form
        [2, 5, 3, 1, 4, 0]

        References
        ==========

        .. [1] https://en.wikipedia.org/wiki/Flavius_Josephus
        .. [2] https://en.wikipedia.org/wiki/Josephus_problem
        .. [3] https://web.archive.org/web/20171008094331/http://www.wou.edu/~burtonl/josephus.html

        r   )dequer(   )	collectionsr~  rE   r8   r*   rb   r   popleftr   )r   r.   r:   rx   r~  Qr   dps           r   josephuszPermutation.josephus  s    L 	&	Q$uQx.!!fs1ay Ah &%&KK		$ !fs1ay  	DG4yr>   c                 6   t        |      }t        t        |dz               }g }	 t        |      D ],  }|||      }|j                  |       |j	                  |       . 	 |j                  |       | j                  |      S # t
        $ r t        d      w xY w)ax  
        Calculates the permutation from the inversion vector.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> from sympy import init_printing
        >>> init_printing(perm_cyclic=False, pretty_print=False)
        >>> Permutation.from_inversion_vector([3, 2, 1, 0, 0])
        Permutation([3, 2, 1, 0, 4, 5])

        r(   z"The inversion vector is not valid.)	r*   rE   r8   r   remove
IndexErrorr+   r   r   )r   	inversionrc   Nr   r]   rY  s          r   from_inversion_vectorz!Permutation.from_inversion_vector?  s     9~tax!	C4[ 	!oC  	A{{4    	CABB	Cs   :B Bc                 v    t        t        |            }t        j                  |       | j	                  |      S )a?  
        Generates a random permutation of length ``n``.

        Uses the underlying Python pseudo-random number generator.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> Permutation.random(2) in (Permutation([1, 0]), Permutation([0, 1]))
        True

        )rE   r8   randomshuffler   )r   r:   
perm_arrays      r   r  zPermutation.random[  s,     %(^
z"{{:&&r>   c                     dg|z  }d}t        |      D ]T  }||dz   z  }||z  |z  }|||z  z  }||||z
  dz
  <   t        ||z
  |      D ]  }||   |dz
  kD  s||xx   dz  cc<    |}V | j                  |      S )a  
        Lexicographic permutation unranking.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation
        >>> from sympy import init_printing
        >>> init_printing(perm_cyclic=False, pretty_print=False)
        >>> a = Permutation.unrank_lex(5, 10)
        >>> a.rank()
        10
        >>> a
        Permutation([0, 2, 4, 1, 3])

        See Also
        ========

        rank, next_lex
        r   r(   )r8   r   )	r   rc   r   r  r  r   	new_psizere  r<   s	            r   r   zPermutation.unrank_lexn  s    , S4Z
t 	Aq1uI	!e+AAeGOD'(Jtax!|$4!8T* 'a=1q5(qMQ&M' E	 {{:&&r>   c           	         | j                   }t        |      }||kD  r-|t        t        ||            z  }t        j                  |      S ||k  r|| j                  }g }|D ]^  }t        |      }t        |      }||dz
  k  s"||dz
  kD  r$t        dj                  |t        |                  |j                  |       ` t	        |      S | S )a  Resize the permutation to the new size ``n``.

        Parameters
        ==========

        n : int
            The new size of the permutation.

        Raises
        ======

        ValueError
            If the permutation cannot be resized to the given size.
            This may only happen when resized to a smaller size than
            the original.

        Examples
        ========

        >>> from sympy.combinatorics import Permutation

        Increasing the size of a permutation:

        >>> p = Permutation(0, 1, 2)
        >>> p = p.resize(5)
        >>> p
        (4)(0 1 2)

        Decreasing the size of the permutation:

        >>> p = p.resize(4)
        >>> p
        (3)(0 1 2)

        If resizing to the specific size breaks the cycles:

        >>> p.resize(2)
        Traceback (most recent call last):
        ...
        ValueError: The permutation cannot be resized to 2 because the
        cycle (0, 1, 2) may break.
        r(   zGThe permutation cannot be resized to {} because the cycle {} may break.)r   r*   rE   r8   rs   r   r   r:  rb   r+   r   rj   r   )	rR   r:   r   lrt   new_cyclic_formr   	cycle_min	cycle_maxs	            r   resizezPermutation.resize  s    V Jq5T%1+&&E&&u--U//K O$ 
2J	J	!# 1Q3(>#VAuU|46 6
 $**51
2 //r>   rI   )r(   )Vr   r   r   r   is_Permutationr   r   rL  r   r   r   classmethodr   r   r   r   r   r   rE   rt   r   rc   r   r   r   staticmethodr   r   r   r   r   r   r   r   r   r   r   r   rW   ry   r_   r   r   r  r  r  r  r   r   r  r  r  r  r  r!  r   r*  r.  r   rb   r:  r>  rD  rF  rH  rJ  rO  rw   rT  r   rX  r\  ra  rg  rk  rp  rr  rx  r|  r  r  r  r   r  print_cyclic__classcell__r   s   @r   rs   rs     s   bH NKLEE!% |"|  2/"&
 # #&&P ( (T    $9 4$ * *X  ,
?"B'(9,@"N`'R 0 0.:,
#';R$/+b)"V % %@"H48#J $ $&+@  , ' ',  *  (     C C:,,<S <,<S <,:x/;b>J6#*  4 * *,D&%(2 h(T #! #!J5 n!F'R)V,\<6 . .` ! !6 ' '$  '  'DAH Lr>   rs   c                 \   |x}}|}d}||k  rH||k  rC| |   | |   k  r| |   ||<   |dz  }|dz  }n| |   ||<   |dz  }|dz  }|||z
  z  }||k  r||k  rC||k  r| |   ||<   |dz  }|dz  }||k  r||k  r&|||z
  dz   z  }|||z
  dz   z  }|||dz    | ||dz    |S |||dz    | ||dz    |S )z
    Merges two sorted arrays and calculates the inversion count.

    Helper function for calculating inversions. This method is
    for internal use only.
    r   r(   r   )	r@  r   leftmidr?  r   r]   r<   	inv_counts	            r   r=  r=    s1    LAAI
c'a5jq6CF?!fDGFAFA!fDGFAFA#q&!I c'a5j c'a&Q	Q	Q c' 	Ez	UQY]	UQY]tAE*DQ  #4	2Dr>   c                   $     e Zd ZdZd fd	Z xZS )r   a  A permutation applied to a symbolic variable.

    Parameters
    ==========

    perm : Permutation
    x : Expr

    Examples
    ========

    >>> from sympy import Symbol
    >>> from sympy.combinatorics import Permutation

    Creating a symbolic permutation function application:

    >>> x = Symbol('x')
    >>> p = Permutation(0, 1, 2)
    >>> p.apply(x)
    AppliedPermutation((0 1 2), x)
    >>> _.subs(x, 1)
    2
    c                    |t         j                  }t        |      }t        |      }t        |t              st        dj                  |            |r|j                  r|j                  |      S t        | )  | ||      }|S )Nz"{} must be a Permutation instance.)r   evaluater   r   rs   r+   r   r   r   r   r   )r   r   r   r  objr   s        r   r   zAppliedPermutation.__new__  sz    (11H~QK$,A  ||zz!}$goc4+
r>   rI   )r   r   r   r   r   r  r  s   @r   r   r     s    . r>   r   c                 h    | j                   |j                   k7  ry | j                  |j                  k(  S rI   )r   r   )lhsrhss     r   _eval_is_eqr  '  s(    
yyCII??coo--r>   )3r  r  r   collections.abcr   	functoolsr   sympy.core.parametersr   sympy.core.basicr   sympy.core.exprr   sympy.core.numbersr	   r
   sympy.core.sympifyr   sympy.matricesr   sympy.polys.polytoolsr   sympy.printing.reprr   sympy.utilities.iterablesr   r   r   r   r   r   sympy.utilities.miscr   mpmath.libmp.libintmathr   sympy.multipledispatchr   r    r,   r=   rC   rF   rN   rM  rP   rs   r=  Permr   r   r  r   r>   r   <module>r     s     # $  3 !   ) & '   % %! ! ' ( +B:z$N2*ZB(bD bJ|'$ |'~O@ 
,,( (V 
+{#. $.r>   