Integer compositions - Combinatorics

Skip to content
Back to top
View this page
Edit this page

# Integer compositions

A composition \(c\) of a nonnegative integer \(n\) is a list of positive integers (the parts of the composition) with total sum \(n\).

This module provides tools for manipulating compositions and enumerated sets of compositions.

EXAMPLES:

Sage

    sage: Composition([5, 3, 1, 3])
    [5, 3, 1, 3]
    sage: list(Compositions(4))
    [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1], [4]]

Python

    >>> from sage.all import *
    >>> Composition([Integer(5), Integer(3), Integer(1), Integer(3)])
    [5, 3, 1, 3]
    >>> list(Compositions(Integer(4)))
    [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1], [4]]

AUTHORS:

- Mike Hansen, Nicolas M. Thiéry

- MuPAD-Combinat developers (algorithms and design inspiration)

- Travis Scrimshaw (2013-02-03): Removed `CombinatorialClass`

class sage.combinat.composition.Composition(parent, lst)

  Bases: `CombinatorialElement`

  Integer compositions.

  A composition of a nonnegative integer \(n\) is a list \((i_1, \ldots, i_k)\) of positive integers with total sum \(n\).

  EXAMPLES:

  The simplest way to create a composition is by specifying its entries as a list, tuple (or other iterable):

  Sage

      sage: Composition([3,1,2])
      [3, 1, 2]
      sage: Composition((3,1,2))
      [3, 1, 2]
      sage: Composition(i for i in range(2,5))
      [2, 3, 4]

  Python

      >>> from sage.all import *
      >>> Composition([Integer(3),Integer(1),Integer(2)])
      [3, 1, 2]
      >>> Composition((Integer(3),Integer(1),Integer(2)))
      [3, 1, 2]
      >>> Composition(i for i in range(Integer(2),Integer(5)))
      [2, 3, 4]

  You can also create a composition from its code. The code of a composition \((i_1, i_2, \ldots, i_k)\) of \(n\) is a list of length \(n\) that consists of a \(1\) followed by \(i_1-1\) zeros, then a \(1\) followed by \(i_2-1\) zeros, and so on.

  Sage

      sage: Composition([4,1,2,3,5]).to_code()
      [1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
      sage: Composition(code=_)
      [4, 1, 2, 3, 5]
      sage: Composition([3,1,2,3,5]).to_code()
      [1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
      sage: Composition(code=_)
      [3, 1, 2, 3, 5]

  [Python]

      >>> from sage.all import *
      >>> Composition([Integer(4),Integer(1),Integer(2),Integer(3),Integer(5)]).to_code()
      [1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
      >>> Composition(code=_)
      [4, 1, 2, 3, 5]
      >>> Composition([Integer(3),Integer(1),Integer(2),Integer(3),Integer(5)]).to_code()
      [1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
      >>> Composition(code=_)
      [3, 1, 2, 3, 5]

  You can also create the composition of \(n\) corresponding to a subset of \(\{1, 2, \ldots, n-1\}\) under the bijection that maps the composition \((i_1, i_2, \ldots, i_k)\) of \(n\) to the subset \(\{i_1, i_1 + i_2, i_1 + i_2 + i_3, \ldots, i_1 + \cdots + i_{k-1}\}\) (see `to_subset()`):

  Sage

      sage: Composition(from_subset=({1, 2, 4}, 5))
      [1, 1, 2, 1]
      sage: Composition([1, 1, 2, 1]).to_subset()
      {1, 2, 4}

  Python

      >>> from sage.all import *
      >>> Composition(from_subset=({Integer(1), Integer(2), Integer(4)}, Integer(5)))
      [1, 1, 2, 1]
      >>> Composition([Integer(1), Integer(1), Integer(2), Integer(1)]).to_subset()
      {1, 2, 4}

  The following notation equivalently specifies the composition from the set \(\{i_1 - 1, i_1 + i_2 - 1, i_1 + i_2 + i_3 - 1, \dots, i_1 + \cdots + i_{k-1} - 1, n-1\}\) or \(\{i_1 - 1, i_1 + i_2 - 1, i_1 + i_2 + i_3 - 1, \dots, i_1 + \cdots + i_{k-1} - 1\}\) and \(n\). This provides compatibility with Python’s \(0\)-indexing.

  Sage

      sage: Composition(descents=[1,0,4,8,11])
      [1, 1, 3, 4, 3]
      sage: Composition(descents=[0,1,3,4])
      [1, 1, 2, 1]
      sage: Composition(descents=([0,1,3],5))
      [1, 1, 2, 1]
      sage: Composition(descents=({0,1,3},5))
      [1, 1, 2, 1]

  [Python]

      >>> from sage.all import *
      >>> Composition(descents=[Integer(1),Integer(0),Integer(4),Integer(8),Integer(11)])
      [1, 1, 3, 4, 3]
      >>> Composition(descents=[Integer(0),Integer(1),Integer(3),Integer(4)])
      [1, 1, 2, 1]
      >>> Composition(descents=([Integer(0),Integer(1),Integer(3)],Integer(5)))
      [1, 1, 2, 1]
      >>> Composition(descents=({Integer(0),Integer(1),Integer(3)},Integer(5)))
      [1, 1, 2, 1]

  An integer composition may be regarded as a sequence. Thus it is an instance of the Python abstract base class `Sequence` allows us to check if objects behave “like” sequences based on implemented methods. Note that `collections.abc.Sequence` is not the same as `sage.structure.sequence.Sequence`:

  Sage

      sage: import collections.abc
      sage: C = Composition([3,2,3])
      sage: isinstance(C, collections.abc.Sequence)
      True
      sage: issubclass(C.__class__, collections.abc.Sequence)
      True

  Python

      >>> from sage.all import *
      >>> import collections.abc
      >>> C = Composition([Integer(3),Integer(2),Integer(3)])
      >>> isinstance(C, collections.abc.Sequence)
      True
      >>> issubclass(C.__class__, collections.abc.Sequence)
      True

  Typically, instances of `collections.abc.Sequence` have a `.count` method. `Composition.count` counts the number of parts of a specified size:

  Sage

      sage: C.count(3)
      2

  [Python]

      >>> from sage.all import *
      >>> C.count(Integer(3))
      2

  EXAMPLES:

  Sage

      sage: C = Composition([3,1,2])
      sage: TestSuite(C).run()

  Python

      >>> from sage.all import *
      >>> C = Composition([Integer(3),Integer(1),Integer(2)])
      >>> TestSuite(C).run()

  complement()

    Return the complement of the composition `self`.

    The complement of a composition \(I\) is defined as follows:

    If \(I\) is the empty composition, then the complement is the empty composition as well. Otherwise, let \(S\) be the descent set of \(I\) (that is, the subset \(\{ i_1, i_1 + i_2, \ldots, i_1 + i_2 + \cdots + i_{k-1} \}\) of \(\{ 1, 2, \ldots, |I|-1 \}\), where \(I\) is written as \((i_1, i_2, \ldots, i_k)\)). Then, the complement of \(I\) is defined as the composition of size \(|I|\) whose descent set is \(\{ 1, 2, \ldots, |I|-1 \} \setminus S\).

    The complement of a composition \(I\) also is the reverse composition (`reversed()`) of the conjugate (`conjugate()`) of \(I\).

    EXAMPLES:

    Sage

        sage: Composition([1, 1, 3, 1, 2, 1, 3]).conjugate()
        [1, 1, 3, 3, 1, 3]
        sage: Composition([1, 1, 3, 1, 2, 1, 3]).complement()
        [3, 1, 3, 3, 1, 1]

    Python

        >>> from sage.all import *
        >>> Composition([Integer(1), Integer(1), Integer(3), Integer(1), Integer(2), Integer(1), Integer(3)]).conjugate()
        [1, 1, 3, 3, 1, 3]
        >>> Composition([Integer(1), Integer(1), Integer(3), Integer(1), Integer(2), Integer(1), Integer(3)]).complement()
        [3, 1, 3, 3, 1, 1]

  conjugate()

    Return the conjugate of the composition `self`.

    The conjugate of a composition \(I\) is defined as the complement (see `complement()`) of the reverse composition (see `reversed()`) of \(I\).

    An equivalent definition of the conjugate goes by saying that the ribbon shape of the conjugate of a composition \(I\) is the conjugate of the ribbon shape of \(I\). (The ribbon shape of a composition is returned by `to_skew_partition()`.)

    This implementation uses the algorithm from mupad-combinat.

    EXAMPLES:

    Sage

        sage: Composition([1, 1, 3, 1, 2, 1, 3]).conjugate()
        [1, 1, 3, 3, 1, 3]

    Python

        >>> from sage.all import *
        >>> Composition([Integer(1), Integer(1), Integer(3), Integer(1), Integer(2), Integer(1), Integer(3)]).conjugate()
        [1, 1, 3, 3, 1, 3]

    The ribbon shape of the conjugate of \(I\) is the conjugate of the ribbon shape of \(I\):

    Sage

        sage: all( I.conjugate().to_skew_partition()                                # needs sage.combinat
        ....:      == I.to_skew_partition().conjugate()
        ....:      for I in Compositions(4) )
        True

    [Python]

        >>> from sage.all import *
        >>> all( I.conjugate().to_skew_partition()                                # needs sage.combinat
        ...      == I.to_skew_partition().conjugate()
        ...      for I in Compositions(Integer(4)) )
        True

  count(n)

    Return the number of parts of size `n`.

    EXAMPLES:

    Sage

        sage: C = Composition([3,2,3])
        sage: C.count(3)
        2
        sage: C.count(2)
        1
        sage: C.count(1)
        0

    Python

        >>> from sage.all import *
        >>> C = Composition([Integer(3),Integer(2),Integer(3)])
        >>> C.count(Integer(3))
        2
        >>> C.count(Integer(2))
        1
        >>> C.count(Integer(1))
        0

  descents(final_descent=False)

    This gives one fewer than the partial sums of the composition.

    This is here to maintain some sort of backward compatibility, even through the original implementation was broken (it gave the wrong answer). The same information can be found in `partial_sums()`.

    See also

    `partial_sums()`

    INPUT:

    - `final_descent` – boolean (default: `False`)

    OUTPUT:

    - the list of partial sums of `self` with each part decremented by \(1\). This includes the sum of all entries when `final_descent` is `True`.

    EXAMPLES:

    Sage

        sage: c = Composition([2,1,3,2])
        sage: c.descents()
        [1, 2, 5]
        sage: c.descents(final_descent=True)
        [1, 2, 5, 7]

    Python

        >>> from sage.all import *
        >>> c = Composition([Integer(2),Integer(1),Integer(3),Integer(2)])
        >>> c.descents()
        [1, 2, 5]
        >>> c.descents(final_descent=True)
        [1, 2, 5, 7]

  fatten(grouping)

    Return the composition fatter than `self`, obtained by grouping together consecutive parts according to `grouping`.

    INPUT:

    - `grouping` – a composition whose sum is the length of `self`

    EXAMPLES:

    Let us start with the composition:

    Sage

        sage: c = Composition([4,5,2,7,1])

    Python

        >>> from sage.all import *
        >>> c = Composition([Integer(4),Integer(5),Integer(2),Integer(7),Integer(1)])

    With `grouping` equal to \((1, \ldots, 1)\), \(c\) is left unchanged:

    Sage

        sage: c.fatten(Composition([1,1,1,1,1]))
        [4, 5, 2, 7, 1]

    [Python]

        >>> from sage.all import *
        >>> c.fatten(Composition([Integer(1),Integer(1),Integer(1),Integer(1),Integer(1)]))
        [4, 5, 2, 7, 1]

    With `grouping` equal to \((\ell)\) where \(\ell\) is the length of \(c\), this yields the coarsest composition above \(c\):

    Sage

        sage: c.fatten(Composition([5]))
        [19]

    Python

        >>> from sage.all import *
        >>> c.fatten(Composition([Integer(5)]))
        [19]

    Other values for `grouping` yield (all the) other compositions coarser than \(c\):

    Sage

        sage: c.fatten(Composition([2,1,2]))
        [9, 2, 8]
        sage: c.fatten(Composition([3,1,1]))
        [11, 7, 1]

    [Python]

        >>> from sage.all import *
        >>> c.fatten(Composition([Integer(2),Integer(1),Integer(2)]))
        [9, 2, 8]
        >>> c.fatten(Composition([Integer(3),Integer(1),Integer(1)]))
        [11, 7, 1]

  fatter()

    Return the set of compositions which are fatter than `self`.

    Complexity for generation: \(O(|c|)\) memory, \(O(|r|)\) time where \(|c|\) is the size of `self` and \(r\) is the result.

    EXAMPLES:

    Sage

        sage: C = Composition([4,5,2]).fatter()
        sage: C.cardinality()
        4
        sage: list(C)
        [[4, 5, 2], [4, 7], [9, 2], [11]]

    Python

        >>> from sage.all import *
        >>> C = Composition([Integer(4),Integer(5),Integer(2)]).fatter()
        >>> C.cardinality()
        4
        >>> list(C)
        [[4, 5, 2], [4, 7], [9, 2], [11]]

    Some extreme cases:

    Sage

        sage: list(Composition([5]).fatter())
        [[5]]
        sage: list(Composition([]).fatter())
        [[]]
        sage: list(Composition([1,1,1,1]).fatter()) == list(Compositions(4))
        True

    [Python]

        >>> from sage.all import *
        >>> list(Composition([Integer(5)]).fatter())
        [[5]]
        >>> list(Composition([]).fatter())
        [[]]
        >>> list(Composition([Integer(1),Integer(1),Integer(1),Integer(1)]).fatter()) == list(Compositions(Integer(4)))
        True

  finer()

    Return the set of compositions which are finer than `self`.

    EXAMPLES:

    Sage

        sage: C = Composition([3,2]).finer()
        sage: C.cardinality()
        8
        sage: C.list()
        [[1, 1, 1, 1, 1], [1, 1, 1, 2], [1, 2, 1, 1], [1, 2, 2], [2, 1, 1, 1], [2, 1, 2], [3, 1, 1], [3, 2]]

        sage: Composition([]).finer()
        {[]}

    Python

        >>> from sage.all import *
        >>> C = Composition([Integer(3),Integer(2)]).finer()
        >>> C.cardinality()
        8
        >>> C.list()
        [[1, 1, 1, 1, 1], [1, 1, 1, 2], [1, 2, 1, 1], [1, 2, 2], [2, 1, 1, 1], [2, 1, 2], [3, 1, 1], [3, 2]]

        >>> Composition([]).finer()
        {[]}

  inf(other, check=True)

    alias of `meet()`.

  is_finer(co2)

    Return `True` if the composition `self` is finer than the composition `co2`; otherwise, return `False`.

    EXAMPLES:

    Sage

        sage: Composition([4,1,2]).is_finer([3,1,3])
        False
        sage: Composition([3,1,3]).is_finer([4,1,2])
        False
        sage: Composition([1,2,2,1,1,2]).is_finer([5,1,3])
        True
        sage: Composition([2,2,2]).is_finer([4,2])
        True

    Python

        >>> from sage.all import *
        >>> Composition([Integer(4),Integer(1),Integer(2)]).is_finer([Integer(3),Integer(1),Integer(3)])
        False
        >>> Composition([Integer(3),Integer(1),Integer(3)]).is_finer([Integer(4),Integer(1),Integer(2)])
        False
        >>> Composition([Integer(1),Integer(2),Integer(2),Integer(1),Integer(1),Integer(2)]).is_finer([Integer(5),Integer(1),Integer(3)])
        True
        >>> Composition([Integer(2),Integer(2),Integer(2)]).is_finer([Integer(4),Integer(2)])
        True

  join(other, check=True)

    Return the join of `self` with a composition `other` of the same size.

    The join of two compositions \(I\) and \(J\) of size \(n\) is the coarsest composition of \(n\) which refines each of \(I\) and \(J\). It can be described as the composition whose descent set is the union of the descent sets of \(I\) and \(J\). It is also the concatenation of \(I_1, I_2, \cdots , I_m\), where \(I = I_1 \bullet I_2 \bullet \ldots \bullet I_m\) is the ribbon decomposition of \(I\) with respect to \(J\) (see `ribbon_decomposition()`).

    INPUT:

    - `other` – composition of same size as `self`

    - `check` – boolean (default: `True`); whether to check the input compositions for having the same size

    OUTPUT: the join of the compositions `self` and `other`

    EXAMPLES:

    Sage

        sage: Composition([3, 1, 1, 3, 1]).join([4, 3, 2])
        [3, 1, 1, 2, 1, 1]
        sage: Composition([9, 6]).join([1, 3, 6, 3, 2])
        [1, 3, 5, 1, 3, 2]
        sage: Composition([9, 6]).join([1, 3, 5, 1, 3, 2])
        [1, 3, 5, 1, 3, 2]
        sage: Composition([1, 1, 1, 1, 1]).join([3, 2])
        [1, 1, 1, 1, 1]
        sage: Composition([4, 2]).join([3, 3])
        [3, 1, 2]
        sage: Composition([]).join([])
        []

    Python

        >>> from sage.all import *
        >>> Composition([Integer(3), Integer(1), Integer(1), Integer(3), Integer(1)]).join([Integer(4), Integer(3), Integer(2)])
        [3, 1, 1, 2, 1, 1]
        >>> Composition([Integer(9), Integer(6)]).join([Integer(1), Integer(3), Integer(6), Integer(3), Integer(2)])
        [1, 3, 5, 1, 3, 2]
        >>> Composition([Integer(9), Integer(6)]).join([Integer(1), Integer(3), Integer(5), Integer(1), Integer(3), Integer(2)])
        [1, 3, 5, 1, 3, 2]
        >>> Composition([Integer(1), Integer(1), Integer(1), Integer(1), Integer(1)]).join([Integer(3), Integer(2)])
        [1, 1, 1, 1, 1]
        >>> Composition([Integer(4), Integer(2)]).join([Integer(3), Integer(3)])
        [3, 1, 2]
        >>> Composition([]).join([])
        []

    Let us verify on small examples that the join of \(I\) and \(J\) refines both of \(I\) and \(J\):

    Sage

        sage: all( all( I.join(J).is_finer(I) and
        ....:           I.join(J).is_finer(J)
        ....:           for J in Compositions(4) )
        ....:      for I in Compositions(4) )
        True

    [Python]

        >>> from sage.all import *
        >>> all( all( I.join(J).is_finer(I) and
        ...           I.join(J).is_finer(J)
        ...           for J in Compositions(Integer(4)) )
        ...      for I in Compositions(Integer(4)) )
        True

    and is the coarsest composition to do so:

    Sage

        sage: all( all( all( K.is_finer(I.join(J))
        ....:                for K in I.finer()
        ....:                if K.is_finer(J) )
        ....:           for J in Compositions(3) )
        ....:      for I in Compositions(3) )
        True

    Python

        >>> from sage.all import *
        >>> all( all( all( K.is_finer(I.join(J))
        ...                for K in I.finer()
        ...                if K.is_finer(J) )
        ...           for J in Compositions(Integer(3)) )
        ...      for I in Compositions(Integer(3)) )
        True

    Let us check that the join of \(I\) and \(J\) is indeed the concatenation of \(I_1, I_2, \cdots , I_m\), where \(I = I_1 \bullet I_2 \bullet \ldots \bullet I_m\) is the ribbon decomposition of \(I\) with respect to \(J\):

    Sage

        sage: all( all( Composition.sum(I.ribbon_decomposition(J)[0])
        ....:           == I.join(J) for J in Compositions(4) )
        ....:      for I in Compositions(4) )
        True

    [Python]

        >>> from sage.all import *
        >>> all( all( Composition.sum(I.ribbon_decomposition(J)[Integer(0)])
        ...           == I.join(J) for J in Compositions(Integer(4)) )
        ...      for I in Compositions(Integer(4)) )
        True

    Also, the descent set of the join of \(I\) and \(J\) is the union of the descent sets of \(I\) and \(J\):

    Sage

        sage: all( all( I.to_subset().union(J.to_subset())
        ....:           == I.join(J).to_subset()
        ....:           for J in Compositions(4) )
        ....:      for I in Compositions(4) )
        True

    Python

        >>> from sage.all import *
        >>> all( all( I.to_subset().union(J.to_subset())
        ...           == I.join(J).to_subset()
        ...           for J in Compositions(Integer(4)) )
        ...      for I in Compositions(Integer(4)) )
        True

    See also

    `meet()`, `ribbon_decomposition()`

    AUTHORS:

    - Darij Grinberg (2013-09-05)

  major_index()

    Return the major index of `self`. The major index is defined as the sum of the descents.

    EXAMPLES:

    Sage

        sage: Composition([1, 1, 3, 1, 2, 1, 3]).major_index()
        31

    Python

        >>> from sage.all import *
        >>> Composition([Integer(1), Integer(1), Integer(3), Integer(1), Integer(2), Integer(1), Integer(3)]).major_index()
        31

  meet(other, check=True)

    Return the meet of `self` with a composition `other` of the same size.

    The meet of two compositions \(I\) and \(J\) of size \(n\) is the finest composition of \(n\) which is coarser than each of \(I\) and \(J\). It can be described as the composition whose descent set is the intersection of the descent sets of \(I\) and \(J\).

    INPUT:

    - `other` – composition of same size as `self`

    - `check` – boolean (default: `True`); whether to check the input compositions for having the same size

    OUTPUT: the meet of the compositions `self` and `other`

    EXAMPLES:

    Sage

        sage: Composition([3, 1, 1, 3, 1]).meet([4, 3, 2])
        [4, 5]
        sage: Composition([9, 6]).meet([1, 3, 6, 3, 2])
        [15]
        sage: Composition([9, 6]).meet([1, 3, 5, 1, 3, 2])
        [9, 6]
        sage: Composition([1, 1, 1, 1, 1]).meet([3, 2])
        [3, 2]
        sage: Composition([4, 2]).meet([3, 3])
        [6]
        sage: Composition([]).meet([])
        []
        sage: Composition([1]).meet([1])
        [1]

    Python

        >>> from sage.all import *
        >>> Composition([Integer(3), Integer(1), Integer(1), Integer(3), Integer(1)]).meet([Integer(4), Integer(3), Integer(2)])
        [4, 5]
        >>> Composition([Integer(9), Integer(6)]).meet([Integer(1), Integer(3), Integer(6), Integer(3), Integer(2)])
        [15]
        >>> Composition([Integer(9), Integer(6)]).meet([Integer(1), Integer(3), Integer(5), Integer(1), Integer(3), Integer(2)])
        [9, 6]
        >>> Composition([Integer(1), Integer(1), Integer(1), Integer(1), Integer(1)]).meet([Integer(3), Integer(2)])
        [3, 2]
        >>> Composition([Integer(4), Integer(2)]).meet([Integer(3), Integer(3)])
        [6]
        >>> Composition([]).meet([])
        []
        >>> Composition([Integer(1)]).meet([Integer(1)])
        [1]

    Let us verify on small examples that the meet of \(I\) and \(J\) is coarser than both of \(I\) and \(J\):

    Sage

        sage: all( all( I.is_finer(I.meet(J)) and
        ....:           J.is_finer(I.meet(J))
        ....:           for J in Compositions(4) )
        ....:      for I in Compositions(4) )
        True

    [Python]

        >>> from sage.all import *
        >>> all( all( I.is_finer(I.meet(J)) and
        ...           J.is_finer(I.meet(J))
        ...           for J in Compositions(Integer(4)) )
        ...      for I in Compositions(Integer(4)) )
        True

    and is the finest composition to do so:

    Sage

        sage: all( all( all( I.meet(J).is_finer(K)
        ....:                for K in I.fatter()
        ....:                if J.is_finer(K) )
        ....:           for J in Compositions(3) )
        ....:      for I in Compositions(3) )
        True

    Python

        >>> from sage.all import *
        >>> all( all( all( I.meet(J).is_finer(K)
        ...                for K in I.fatter()
        ...                if J.is_finer(K) )
        ...           for J in Compositions(Integer(3)) )
        ...      for I in Compositions(Integer(3)) )
        True

    The descent set of the meet of \(I\) and \(J\) is the intersection of the descent sets of \(I\) and \(J\):

    Sage

        sage: def test_meet(n):
        ....:     return all( all( I.to_subset().intersection(J.to_subset())
        ....:                      == I.meet(J).to_subset()
        ....:                      for J in Compositions(n) )
        ....:                 for I in Compositions(n) )
        sage: all( test_meet(n) for n in range(1, 5) )
        True

    [Python]

        >>> from sage.all import *
        >>> def test_meet(n):
        ...     return all( all( I.to_subset().intersection(J.to_subset())
        ...                      == I.meet(J).to_subset()
        ...                      for J in Compositions(n) )
        ...                 for I in Compositions(n) )
        >>> all( test_meet(n) for n in range(Integer(1), Integer(5)) )
        True

    See also

    `join()`

    AUTHORS:

    - Darij Grinberg (2013-09-05)

  near_concatenation(other)

    Return the near-concatenation of two nonempty compositions `self` and `other`.

    The near-concatenation \(I \odot J\) of two nonempty compositions \(I\) and \(J\) is defined as the composition \((i_1, i_2, \ldots , i_{n-1}, i_n + j_1, j_2, j_3, \ldots , j_m)\), where \((i_1, i_2, \ldots , i_n) = I\) and \((j_1, j_2, \ldots , j_m) = J\).

    This method returns `None` if one of the two input compositions is empty.

    EXAMPLES:

    Sage

        sage: Composition([1, 1, 3]).near_concatenation(Composition([4, 1, 2]))
        [1, 1, 7, 1, 2]
        sage: Composition([6]).near_concatenation(Composition([1, 5]))
        [7, 5]
        sage: Composition([1, 5]).near_concatenation(Composition([6]))
        [1, 11]

    Python

        >>> from sage.all import *
        >>> Composition([Integer(1), Integer(1), Integer(3)]).near_concatenation(Composition([Integer(4), Integer(1), Integer(2)]))
        [1, 1, 7, 1, 2]
        >>> Composition([Integer(6)]).near_concatenation(Composition([Integer(1), Integer(5)]))
        [7, 5]
        >>> Composition([Integer(1), Integer(5)]).near_concatenation(Composition([Integer(6)]))
        [1, 11]

  partial_sums(final=True)

    The partial sums of the sequence defined by the entries of the composition.

    If \(I = (i_1, \ldots, i_m)\) is a composition, then the partial sums of the entries of the composition are \([i_1, i_1 + i_2, \ldots, i_1 + i_2 + \cdots + i_m]\).

    INPUT:

    - `final` – boolean (default: `True`); whether or not to include the final partial sum, which is always the size of the composition

    See also

    `to_subset()`

    EXAMPLES:

    Sage

        sage: Composition([1,1,3,1,2,1,3]).partial_sums()
        [1, 2, 5, 6, 8, 9, 12]

    Python

        >>> from sage.all import *
        >>> Composition([Integer(1),Integer(1),Integer(3),Integer(1),Integer(2),Integer(1),Integer(3)]).partial_sums()
        [1, 2, 5, 6, 8, 9, 12]

    With `final = False`, the last partial sum is not included:

    Sage

        sage: Composition([1,1,3,1,2,1,3]).partial_sums(final=False)
        [1, 2, 5, 6, 8, 9]

    [Python]

        >>> from sage.all import *
        >>> Composition([Integer(1),Integer(1),Integer(3),Integer(1),Integer(2),Integer(1),Integer(3)]).partial_sums(final=False)
        [1, 2, 5, 6, 8, 9]

  peaks()

    Return a list of the peaks of the composition `self`.

    The peaks of a composition are the descents which do not immediately follow another descent.

    EXAMPLES:

    Sage

        sage: Composition([1, 1, 3, 1, 2, 1, 3]).peaks()
        [4, 7]

    Python

        >>> from sage.all import *
        >>> Composition([Integer(1), Integer(1), Integer(3), Integer(1), Integer(2), Integer(1), Integer(3)]).peaks()
        [4, 7]

  refinement_splitting(J)

    Return the refinement splitting of `self` according to `J`.

    INPUT:

    - `J` – a composition such that `self` is finer than `J`

    OUTPUT:

    - the unique list of compositions \((I^{(p)})_{p=1, \ldots , m}\), obtained by splitting \(I\), such that \(|I^{(p)}| = J_p\) for all \(p = 1, \ldots, m\).

    See also

    `refinement_splitting_lengths()`

    EXAMPLES:

    Sage

        sage: Composition([1,2,2,1,1,2]).refinement_splitting([5,1,3])
        [[1, 2, 2], [1], [1, 2]]
        sage: Composition([]).refinement_splitting([])
        []
        sage: Composition([3]).refinement_splitting([2])
        Traceback (most recent call last):
        ...
        ValueError: compositions self (= [3]) and J (= [2]) must be of the same size
        sage: Composition([2,1]).refinement_splitting([1,2])
        Traceback (most recent call last):
        ...
        ValueError: composition J (= [2, 1]) does not refine self (= [1, 2])

    Python

        >>> from sage.all import *
        >>> Composition([Integer(1),Integer(2),Integer(2),Integer(1),Integer(1),Integer(2)]).refinement_splitting([Integer(5),Integer(1),Integer(3)])
        [[1, 2, 2], [1], [1, 2]]
        >>> Composition([]).refinement_splitting([])
        []
        >>> Composition([Integer(3)]).refinement_splitting([Integer(2)])
        Traceback (most recent call last):
        ...
        ValueError: compositions self (= [3]) and J (= [2]) must be of the same size
        >>> Composition([Integer(2),Integer(1)]).refinement_splitting([Integer(1),Integer(2)])
        Traceback (most recent call last):
        ...
        ValueError: composition J (= [2, 1]) does not refine self (= [1, 2])

  refinement_splitting_lengths(J)

    Return the lengths of the compositions in the refinement splitting of `self` according to `J`.

    See also

    `refinement_splitting()` for the definition of refinement splitting

    EXAMPLES:

    Sage

        sage: Composition([1,2,2,1,1,2]).refinement_splitting_lengths([5,1,3])
        [3, 1, 2]
        sage: Composition([]).refinement_splitting_lengths([])
        []
        sage: Composition([3]).refinement_splitting_lengths([2])
        Traceback (most recent call last):
        ...
        ValueError: compositions self (= [3]) and J (= [2]) must be of the same size
        sage: Composition([2,1]).refinement_splitting_lengths([1,2])
        Traceback (most recent call last):
        ...
        ValueError: composition J (= [2, 1]) does not refine self (= [1, 2])

    Python

        >>> from sage.all import *
        >>> Composition([Integer(1),Integer(2),Integer(2),Integer(1),Integer(1),Integer(2)]).refinement_splitting_lengths([Integer(5),Integer(1),Integer(3)])
        [3, 1, 2]
        >>> Composition([]).refinement_splitting_lengths([])
        []
        >>> Composition([Integer(3)]).refinement_splitting_lengths([Integer(2)])
        Traceback (most recent call last):
        ...
        ValueError: compositions self (= [3]) and J (= [2]) must be of the same size
        >>> Composition([Integer(2),Integer(1)]).refinement_splitting_lengths([Integer(1),Integer(2)])
        Traceback (most recent call last):
        ...
        ValueError: composition J (= [2, 1]) does not refine self (= [1, 2])

  reversed()

    Return the reverse composition of `self`.

    The reverse composition of a composition \((i_1, i_2, \ldots, i_k)\) is defined as the composition \((i_k, i_{k-1}, \ldots, i_1)\).

    EXAMPLES:

    Sage

        sage: Composition([1, 1, 3, 1, 2, 1, 3]).reversed()
        [3, 1, 2, 1, 3, 1, 1]

    Python

        >>> from sage.all import *
        >>> Composition([Integer(1), Integer(1), Integer(3), Integer(1), Integer(2), Integer(1), Integer(3)]).reversed()
        [3, 1, 2, 1, 3, 1, 1]

  ribbon_decomposition(other, check=True)

    Return a pair describing the ribbon decomposition of a composition `self` with respect to a composition `other` of the same size.

    If \(I\) and \(J\) are two compositions of the same nonzero size, then the ribbon decomposition of \(I\) with respect to \(J\) is defined as follows: Write \(I\) and \(J\) as \(I = (i_1, i_2, \ldots , i_n)\) and \(J = (j_1, j_2, \ldots , j_m)\). Then, the equality \(I = I_1 \bullet I_2 \bullet \ldots \bullet I_m\) holds for a unique \(m\)-tuple \((I_1, I_2, \ldots , I_m)\) of compositions such that each \(I_k\) has size \(j_k\) and for a unique choice of \(m-1\) signs \(\bullet\) each of which is either the concatenation sign \(\cdot\) or the near-concatenation sign \(\odot\) (see `__add__()` and `near_concatenation()` for the definitions of these two signs). This \(m\)-tuple and this choice of signs together are said to form the ribbon decomposition of \(I\) with respect to \(J\). If \(I\) and \(J\) are empty, then the same definition applies, except that there are \(0\) rather than \(m-1\) signs.

    See Section 4.8 of [NCSF1].

    INPUT:

    - `other` – composition of same size as `self`

    - `check` – boolean (default: `True`); whether to check the input compositions for having the same size

    OUTPUT:

    - a pair `(u, v)`, where `u` is a tuple of compositions (corresponding to the \(m\)-tuple \((I_1, I_2, \ldots , I_m)\) in the above definition), and `v` is a tuple of \(0`s and `1`s (encoding the choice of signs `\bullet\) in the above definition, with a \(0\) standing for \(\cdot\) and a \(1\) standing for \(\odot\)).

    EXAMPLES:

    Sage

        sage: Composition([3, 1, 1, 3, 1]).ribbon_decomposition([4, 3, 2])
        (([3, 1], [1, 2], [1, 1]), (0, 1))
        sage: Composition([9, 6]).ribbon_decomposition([1, 3, 6, 3, 2])
        (([1], [3], [5, 1], [3], [2]), (1, 1, 1, 1))
        sage: Composition([9, 6]).ribbon_decomposition([1, 3, 5, 1, 3, 2])
        (([1], [3], [5], [1], [3], [2]), (1, 1, 0, 1, 1))
        sage: Composition([1, 1, 1, 1, 1]).ribbon_decomposition([3, 2])
        (([1, 1, 1], [1, 1]), (0,))
        sage: Composition([4, 2]).ribbon_decomposition([6])
        (([4, 2],), ())
        sage: Composition([]).ribbon_decomposition([])
        ((), ())

    Python

        >>> from sage.all import *
        >>> Composition([Integer(3), Integer(1), Integer(1), Integer(3), Integer(1)]).ribbon_decomposition([Integer(4), Integer(3), Integer(2)])
        (([3, 1], [1, 2], [1, 1]), (0, 1))
        >>> Composition([Integer(9), Integer(6)]).ribbon_decomposition([Integer(1), Integer(3), Integer(6), Integer(3), Integer(2)])
        (([1], [3], [5, 1], [3], [2]), (1, 1, 1, 1))
        >>> Composition([Integer(9), Integer(6)]).ribbon_decomposition([Integer(1), Integer(3), Integer(5), Integer(1), Integer(3), Integer(2)])
        (([1], [3], [5], [1], [3], [2]), (1, 1, 0, 1, 1))
        >>> Composition([Integer(1), Integer(1), Integer(1), Integer(1), Integer(1)]).ribbon_decomposition([Integer(3), Integer(2)])
        (([1, 1, 1], [1, 1]), (0,))
        >>> Composition([Integer(4), Integer(2)]).ribbon_decomposition([Integer(6)])
        (([4, 2],), ())
        >>> Composition([]).ribbon_decomposition([])
        ((), ())

    Let us check that the defining property \(I = I_1 \bullet I_2 \bullet \ldots \bullet I_m\) is satisfied:

    Sage

        sage: def compose_back(u, v):
        ....:     comp = u[0]
        ....:     r = len(v)
        ....:     if len(u) != r + 1:
        ....:         raise ValueError("something is wrong")
        ....:     for i in range(r):
        ....:         if v[i] == 0:
        ....:             comp += u[i + 1]
        ....:         else:
        ....:             comp = comp.near_concatenation(u[i + 1])
        ....:     return comp
        sage: all( all( all( compose_back(*(I.ribbon_decomposition(J))) == I
        ....:                for J in Compositions(n) )
        ....:           for I in Compositions(n) )
        ....:      for n in range(1, 5) )
        True

    [Python]

        >>> from sage.all import *
        >>> def compose_back(u, v):
        ...     comp = u[Integer(0)]
        ...     r = len(v)
        ...     if len(u) != r + Integer(1):
        ...         raise ValueError("something is wrong")
        ...     for i in range(r):
        ...         if v[i] == Integer(0):
        ...             comp += u[i + Integer(1)]
        ...         else:
        ...             comp = comp.near_concatenation(u[i + Integer(1)])
        ...     return comp
        >>> all( all( all( compose_back(*(I.ribbon_decomposition(J))) == I
        ...                for J in Compositions(n) )
        ...           for I in Compositions(n) )
        ...      for n in range(Integer(1), Integer(5)) )
        True

    AUTHORS:

    - Darij Grinberg (2013-08-29)

  shuffle_product(other, overlap=False)

    The (overlapping) shuffles of `self` and `other`.

    Suppose \(I = (i_1, \ldots, i_k)\) and \(J = (j_1, \ldots, j_l)\) are two compositions. A shuffle of \(I\) and \(J\) is a composition of length \(k + l\) that contains both \(I\) and \(J\) as subsequences.

    More generally, an overlapping shuffle of \(I\) and \(J\) is obtained by distributing the elements of \(I\) and \(J\) (preserving the relative ordering of these elements) among the positions of an empty list; an element of \(I\) and an element of \(J\) are permitted to share the same position, in which case they are replaced by their sum. In particular, a shuffle of \(I\) and \(J\) is an overlapping shuffle of \(I\) and \(J\).

    INPUT:

    - `other` – composition

    - `overlap` – boolean (default: `False`); if `True`, the overlapping shuffle product is returned

    OUTPUT:

    An enumerated set (allowing for multiplicities)

    EXAMPLES:

    The shuffle product of \([2,2]\) and \([1,1,3]\):

    Sage

        sage: alph = Composition([2,2])
        sage: beta = Composition([1,1,3])
        sage: S = alph.shuffle_product(beta); S                                     # needs sage.combinat
        Shuffle product of [2, 2] and [1, 1, 3]
        sage: S.list()                                                              # needs sage.combinat
        [[2, 2, 1, 1, 3], [2, 1, 2, 1, 3], [2, 1, 1, 2, 3], [2, 1, 1, 3, 2],
         [1, 2, 2, 1, 3], [1, 2, 1, 2, 3], [1, 2, 1, 3, 2], [1, 1, 2, 2, 3],
         [1, 1, 2, 3, 2], [1, 1, 3, 2, 2]]

    Python

        >>> from sage.all import *
        >>> alph = Composition([Integer(2),Integer(2)])
        >>> beta = Composition([Integer(1),Integer(1),Integer(3)])
        >>> S = alph.shuffle_product(beta); S                                     # needs sage.combinat
        Shuffle product of [2, 2] and [1, 1, 3]
        >>> S.list()                                                              # needs sage.combinat
        [[2, 2, 1, 1, 3], [2, 1, 2, 1, 3], [2, 1, 1, 2, 3], [2, 1, 1, 3, 2],
         [1, 2, 2, 1, 3], [1, 2, 1, 2, 3], [1, 2, 1, 3, 2], [1, 1, 2, 2, 3],
         [1, 1, 2, 3, 2], [1, 1, 3, 2, 2]]

    The overlapping shuffle product of \([2,2]\) and \([1,1,3]\):

    Sage

        sage: alph = Composition([2,2])
        sage: beta = Composition([1,1,3])
        sage: O = alph.shuffle_product(beta, overlap=True); O                       # needs sage.combinat
        Overlapping shuffle product of [2, 2] and [1, 1, 3]
        sage: O.list()                                                              # needs sage.combinat
        [[2, 2, 1, 1, 3], [2, 1, 2, 1, 3], [2, 1, 1, 2, 3], [2, 1, 1, 3, 2],
         [1, 2, 2, 1, 3], [1, 2, 1, 2, 3], [1, 2, 1, 3, 2], [1, 1, 2, 2, 3],
         [1, 1, 2, 3, 2], [1, 1, 3, 2, 2],
         [3, 2, 1, 3], [2, 3, 1, 3], [3, 1, 2, 3], [2, 1, 3, 3], [3, 1, 3, 2],
         [2, 1, 1, 5], [1, 3, 2, 3], [1, 2, 3, 3], [1, 3, 3, 2], [1, 2, 1, 5],
         [1, 1, 5, 2], [1, 1, 2, 5],
         [3, 3, 3], [3, 1, 5], [1, 3, 5]]

    [Python]

        >>> from sage.all import *
        >>> alph = Composition([Integer(2),Integer(2)])
        >>> beta = Composition([Integer(1),Integer(1),Integer(3)])
        >>> O = alph.shuffle_product(beta, overlap=True); O                       # needs sage.combinat
        Overlapping shuffle product of [2, 2] and [1, 1, 3]
        >>> O.list()                                                              # needs sage.combinat
        [[2, 2, 1, 1, 3], [2, 1, 2, 1, 3], [2, 1, 1, 2, 3], [2, 1, 1, 3, 2],
         [1, 2, 2, 1, 3], [1, 2, 1, 2, 3], [1, 2, 1, 3, 2], [1, 1, 2, 2, 3],
         [1, 1, 2, 3, 2], [1, 1, 3, 2, 2],
         [3, 2, 1, 3], [2, 3, 1, 3], [3, 1, 2, 3], [2, 1, 3, 3], [3, 1, 3, 2],
         [2, 1, 1, 5], [1, 3, 2, 3], [1, 2, 3, 3], [1, 3, 3, 2], [1, 2, 1, 5],
         [1, 1, 5, 2], [1, 1, 2, 5],
         [3, 3, 3], [3, 1, 5], [1, 3, 5]]

    Note that the shuffle product of two compositions can include the same composition more than once since a composition can be a shuffle of two compositions in several ways. For example:

    Sage

        sage: # needs sage.combinat
        sage: w1 = Composition([1])
        sage: S = w1.shuffle_product(w1); S
        Shuffle product of [1] and [1]
        sage: S.list()
        [[1, 1], [1, 1]]
        sage: O = w1.shuffle_product(w1, overlap=True); O
        Overlapping shuffle product of [1] and [1]
        sage: O.list()
        [[1, 1], [1, 1], [2]]

    Python

        >>> from sage.all import *
        >>> # needs sage.combinat
        >>> w1 = Composition([Integer(1)])
        >>> S = w1.shuffle_product(w1); S
        Shuffle product of [1] and [1]
        >>> S.list()
        [[1, 1], [1, 1]]
        >>> O = w1.shuffle_product(w1, overlap=True); O
        Overlapping shuffle product of [1] and [1]
        >>> O.list()
        [[1, 1], [1, 1], [2]]

  size()

    Return the size of `self`, that is the sum of its parts.

    EXAMPLES:

    Sage

        sage: Composition([7,1,3]).size()
        11

    Python

        >>> from sage.all import *
        >>> Composition([Integer(7),Integer(1),Integer(3)]).size()
        11

  specht_module(base_ring=None)

    Return the Specht module corresponding to `self`.

    EXAMPLES:

    Sage

        sage: SM = Composition([1,2,2]).specht_module(QQ); SM                       # needs sage.combinat sage.modules
        Specht module of [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)] over Rational Field
        sage: s = SymmetricFunctions(QQ).s()                                        # needs sage.combinat sage.modules
        sage: s(SM.frobenius_image())                                               # needs sage.combinat sage.modules
        s[2, 2, 1]

    Python

        >>> from sage.all import *
        >>> SM = Composition([Integer(1),Integer(2),Integer(2)]).specht_module(QQ); SM                       # needs sage.combinat sage.modules
        Specht module of [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)] over Rational Field
        >>> s = SymmetricFunctions(QQ).s()                                        # needs sage.combinat sage.modules
        >>> s(SM.frobenius_image())                                               # needs sage.combinat sage.modules
        s[2, 2, 1]

  specht_module_dimension(base_ring=None)

    Return the dimension of the Specht module corresponding to `self`.

    INPUT:

    - `base_ring` – (default: \(\QQ\)) the base ring

    EXAMPLES:

    Sage

        sage: Composition([1,2,2]).specht_module_dimension()                        # needs sage.combinat sage.modules
        5
        sage: Composition([1,2,2]).specht_module_dimension(GF(2))                   # needs sage.combinat sage.modules sage.rings.finite_rings
        5

    Python

        >>> from sage.all import *
        >>> Composition([Integer(1),Integer(2),Integer(2)]).specht_module_dimension()                        # needs sage.combinat sage.modules
        5
        >>> Composition([Integer(1),Integer(2),Integer(2)]).specht_module_dimension(GF(Integer(2)))                   # needs sage.combinat sage.modules sage.rings.finite_rings
        5

  static sum(compositions)

    Return the concatenation of the given compositions.

    INPUT:

    - `compositions` – list (or iterable) of compositions

    EXAMPLES:

    Sage

        sage: Composition.sum([Composition([1, 1, 3]), Composition([4, 1, 2]), Composition([3,1])])
        [1, 1, 3, 4, 1, 2, 3, 1]

    Python

        >>> from sage.all import *
        >>> Composition.sum([Composition([Integer(1), Integer(1), Integer(3)]), Composition([Integer(4), Integer(1), Integer(2)]), Composition([Integer(3),Integer(1)])])
        [1, 1, 3, 4, 1, 2, 3, 1]

    Any iterable can be provided as input:

    Sage

        sage: Composition.sum([Composition([i,i]) for i in [4,1,3]])
        [4, 4, 1, 1, 3, 3]

    [Python]

        >>> from sage.all import *
        >>> Composition.sum([Composition([i,i]) for i in [Integer(4),Integer(1),Integer(3)]])
        [4, 4, 1, 1, 3, 3]

    Empty inputs are handled gracefully:

    Sage

        sage: Composition.sum([]) == Composition([])
        True

    Python

        >>> from sage.all import *
        >>> Composition.sum([]) == Composition([])
        True

  sup(other, check=True)

    alias of `join()`.

  to_code()

    Return the code of the composition `self`.

    The code of a composition \(I\) is a list of length \(\mathrm{size}(I)\) of 1s and 0s such that there is a 1 wherever a new part starts. (Exceptional case: When the composition is empty, the code is `[0]`.)

    EXAMPLES:

    Sage

        sage: Composition([4,1,2,3,5]).to_code()
        [1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]

    Python

        >>> from sage.all import *
        >>> Composition([Integer(4),Integer(1),Integer(2),Integer(3),Integer(5)]).to_code()
        [1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]

  to_partition()

    Return the partition obtained by sorting `self` into decreasing order.

    EXAMPLES:

    Sage

        sage: Composition([2,1,3]).to_partition()                                   # needs sage.combinat
        [3, 2, 1]
        sage: Composition([4,2,2]).to_partition()                                   # needs sage.combinat
        [4, 2, 2]
        sage: Composition([]).to_partition()                                        # needs sage.combinat
        []

    Python

        >>> from sage.all import *
        >>> Composition([Integer(2),Integer(1),Integer(3)]).to_partition()                                   # needs sage.combinat
        [3, 2, 1]
        >>> Composition([Integer(4),Integer(2),Integer(2)]).to_partition()                                   # needs sage.combinat
        [4, 2, 2]
        >>> Composition([]).to_partition()                                        # needs sage.combinat
        []

  to_skew_partition(overlap=1)

    Return the skew partition obtained from `self`.

    This is a skew partition whose rows have the entries of `self` as their length, taken in reverse order (so the first entry of `self` is the length of the lowermost row, etc.). The parameter `overlap` indicates the number of cells on each row that are directly below cells of the previous row. When it is set to \(1\) (its default value), the result is the ribbon shape of `self`.

    EXAMPLES:

    Sage

        sage: # needs sage.combinat
        sage: Composition([3,4,1]).to_skew_partition()
        [6, 6, 3] / [5, 2]
        sage: Composition([3,4,1]).to_skew_partition(overlap=0)
        [8, 7, 3] / [7, 3]
        sage: Composition([]).to_skew_partition()
        [] / []
        sage: Composition([1,2]).to_skew_partition()
        [2, 1] / []
        sage: Composition([2,1]).to_skew_partition()
        [2, 2] / [1]

    Python

        >>> from sage.all import *
        >>> # needs sage.combinat
        >>> Composition([Integer(3),Integer(4),Integer(1)]).to_skew_partition()
        [6, 6, 3] / [5, 2]
        >>> Composition([Integer(3),Integer(4),Integer(1)]).to_skew_partition(overlap=Integer(0))
        [8, 7, 3] / [7, 3]
        >>> Composition([]).to_skew_partition()
        [] / []
        >>> Composition([Integer(1),Integer(2)]).to_skew_partition()
        [2, 1] / []
        >>> Composition([Integer(2),Integer(1)]).to_skew_partition()
        [2, 2] / [1]

  to_subset(final=False)

    The subset corresponding to `self` under the bijection (see below) between compositions of \(n\) and subsets of \(\{1, 2, \ldots, n-1\}\).

    The bijection maps a composition \((i_1, \ldots, i_k)\) of \(n\) to \(\{i_1, i_1 + i_2, i_1 + i_2 + i_3, \ldots, i_1 + \cdots + i_{k-1}\}\).

    INPUT:

    - `final` – boolean (default: `False`); whether or not to include the final partial sum, which is always the size of the composition

    See also

    `partial_sums()`

    EXAMPLES:

    Sage

        sage: Composition([1,1,3,1,2,1,3]).to_subset()
        {1, 2, 5, 6, 8, 9}
        sage: for I in Compositions(3): print(I.to_subset())
        {1, 2}
        {1}
        {2}
        {}

    Python

        >>> from sage.all import *
        >>> Composition([Integer(1),Integer(1),Integer(3),Integer(1),Integer(2),Integer(1),Integer(3)]).to_subset()
        {1, 2, 5, 6, 8, 9}
        >>> for I in Compositions(Integer(3)): print(I.to_subset())
        {1, 2}
        {1}
        {2}
        {}

    With `final=True`, the sum of all the elements of the composition is included in the subset:

    Sage

        sage: Composition([1,1,3,1,2,1,3]).to_subset(final=True)
        {1, 2, 5, 6, 8, 9, 12}

    [Python]

        >>> from sage.all import *
        >>> Composition([Integer(1),Integer(1),Integer(3),Integer(1),Integer(2),Integer(1),Integer(3)]).to_subset(final=True)
        {1, 2, 5, 6, 8, 9, 12}

  wll_gt(co2)

    Return `True` if the composition `self` is greater than the composition `co2` with respect to the wll-ordering; otherwise, return `False`.

    The wll-ordering is a total order on the set of all compositions defined as follows: A composition \(I\) is greater than a composition \(J\) if and only if one of the following conditions holds:

    - The size of \(I\) is greater than the size of \(J\).

    - The size of \(I\) equals the size of \(J\), but the length of \(I\) is greater than the length of \(J\).

    - The size of \(I\) equals the size of \(J\), and the length of \(I\) equals the length of \(J\), but \(I\) is lexicographically greater than \(J\).

    (“wll-ordering” is short for “weight, length, lexicographic ordering”.)

    EXAMPLES:

    Sage

        sage: Composition([4,1,2]).wll_gt([3,1,3])
        True
        sage: Composition([7]).wll_gt([4,1,2])
        False
        sage: Composition([8]).wll_gt([4,1,2])
        True
        sage: Composition([3,2,2,2]).wll_gt([5,2])
        True
        sage: Composition([]).wll_gt([3])
        False
        sage: Composition([2,1]).wll_gt([2,1])
        False
        sage: Composition([2,2,2]).wll_gt([4,2])
        True
        sage: Composition([4,2]).wll_gt([2,2,2])
        False
        sage: Composition([1,1,2]).wll_gt([2,2])
        True
        sage: Composition([2,2]).wll_gt([1,3])
        True
        sage: Composition([2,1,2]).wll_gt([])
        True

    Python

        >>> from sage.all import *
        >>> Composition([Integer(4),Integer(1),Integer(2)]).wll_gt([Integer(3),Integer(1),Integer(3)])
        True
        >>> Composition([Integer(7)]).wll_gt([Integer(4),Integer(1),Integer(2)])
        False
        >>> Composition([Integer(8)]).wll_gt([Integer(4),Integer(1),Integer(2)])
        True
        >>> Composition([Integer(3),Integer(2),Integer(2),Integer(2)]).wll_gt([Integer(5),Integer(2)])
        True
        >>> Composition([]).wll_gt([Integer(3)])
        False
        >>> Composition([Integer(2),Integer(1)]).wll_gt([Integer(2),Integer(1)])
        False
        >>> Composition([Integer(2),Integer(2),Integer(2)]).wll_gt([Integer(4),Integer(2)])
        True
        >>> Composition([Integer(4),Integer(2)]).wll_gt([Integer(2),Integer(2),Integer(2)])
        False
        >>> Composition([Integer(1),Integer(1),Integer(2)]).wll_gt([Integer(2),Integer(2)])
        True
        >>> Composition([Integer(2),Integer(2)]).wll_gt([Integer(1),Integer(3)])
        True
        >>> Composition([Integer(2),Integer(1),Integer(2)]).wll_gt([])
        True

class sage.combinat.composition.Compositions(is_infinite=False, category=None)

  Bases: `UniqueRepresentation`, `Parent`

  Set of integer compositions.

  A composition \(c\) of a nonnegative integer \(n\) is a list of positive integers with total sum \(n\).

  See also

  - `Composition`

  - `Partitions`

  - `IntegerVectors`

  EXAMPLES:

  There are 8 compositions of 4:

  Sage

      sage: Compositions(4).cardinality()
      8

  Python

      >>> from sage.all import *
      >>> Compositions(Integer(4)).cardinality()
      8

  Here is the list of them:

  Sage

      sage: Compositions(4).list()
      [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1], [4]]

  [Python]

      >>> from sage.all import *
      >>> Compositions(Integer(4)).list()
      [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1], [4]]

  You can use the `.first()` method to get the ‘first’ composition of a number:

  Sage

      sage: Compositions(4).first()
      [1, 1, 1, 1]

  Python

      >>> from sage.all import *
      >>> Compositions(Integer(4)).first()
      [1, 1, 1, 1]

  You can also calculate the ‘next’ composition given the current one:

  Sage

      sage: Compositions(4).next([1,1,2])
      [1, 2, 1]

  [Python]

      >>> from sage.all import *
      >>> Compositions(Integer(4)).next([Integer(1),Integer(1),Integer(2)])
      [1, 2, 1]

  If \(n\) is not specified, this returns the combinatorial class of all (nonnegative) integer compositions:

  Sage

      sage: Compositions()
      Compositions of nonnegative integers
      sage: [] in Compositions()
      True
      sage: [2,3,1] in Compositions()
      True
      sage: [-2,3,1] in Compositions()
      False

  Python

      >>> from sage.all import *
      >>> Compositions()
      Compositions of nonnegative integers
      >>> [] in Compositions()
      True
      >>> [Integer(2),Integer(3),Integer(1)] in Compositions()
      True
      >>> [-Integer(2),Integer(3),Integer(1)] in Compositions()
      False

  If \(n\) is specified, it returns the class of compositions of \(n\):

  Sage

      sage: Compositions(3)
      Compositions of 3
      sage: list(Compositions(3))
      [[1, 1, 1], [1, 2], [2, 1], [3]]
      sage: Compositions(3).cardinality()
      4

  [Python]

      >>> from sage.all import *
      >>> Compositions(Integer(3))
      Compositions of 3
      >>> list(Compositions(Integer(3)))
      [[1, 1, 1], [1, 2], [2, 1], [3]]
      >>> Compositions(Integer(3)).cardinality()
      4

  The following examples show how to test whether or not an object is a composition:

  Sage

      sage: [3,4] in Compositions()
      True
      sage: [3,4] in Compositions(7)
      True
      sage: [3,4] in Compositions(5)
      False

  Python

      >>> from sage.all import *
      >>> [Integer(3),Integer(4)] in Compositions()
      True
      >>> [Integer(3),Integer(4)] in Compositions(Integer(7))
      True
      >>> [Integer(3),Integer(4)] in Compositions(Integer(5))
      False

  Similarly, one can check whether or not an object is a composition which satisfies further constraints:

  Sage

      sage: [4,2] in Compositions(6, inner=[2,2])
      True
      sage: [4,2] in Compositions(6, inner=[2,3])
      False
      sage: [4,1] in Compositions(5, inner=[2,1], max_slope = 0)
      True

  [Python]

      >>> from sage.all import *
      >>> [Integer(4),Integer(2)] in Compositions(Integer(6), inner=[Integer(2),Integer(2)])
      True
      >>> [Integer(4),Integer(2)] in Compositions(Integer(6), inner=[Integer(2),Integer(3)])
      False
      >>> [Integer(4),Integer(1)] in Compositions(Integer(5), inner=[Integer(2),Integer(1)], max_slope = Integer(0))
      True

  An example with incompatible constraints:

  Sage

      sage: [4,2] in Compositions(6, inner=[2,2], min_part=3)
      False

  Python

      >>> from sage.all import *
      >>> [Integer(4),Integer(2)] in Compositions(Integer(6), inner=[Integer(2),Integer(2)], min_part=Integer(3))
      False

  The options `length`, `min_length`, and `max_length` can be used to set length constraints on the compositions. For example, the compositions of 4 of length equal to, at least, and at most 2 are given by:

  Sage

      sage: Compositions(4, length=2).list()
      [[3, 1], [2, 2], [1, 3]]
      sage: Compositions(4, min_length=2).list()
      [[3, 1], [2, 2], [2, 1, 1], [1, 3], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]]
      sage: Compositions(4, max_length=2).list()
      [[4], [3, 1], [2, 2], [1, 3]]

  [Python]

      >>> from sage.all import *
      >>> Compositions(Integer(4), length=Integer(2)).list()
      [[3, 1], [2, 2], [1, 3]]
      >>> Compositions(Integer(4), min_length=Integer(2)).list()
      [[3, 1], [2, 2], [2, 1, 1], [1, 3], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]]
      >>> Compositions(Integer(4), max_length=Integer(2)).list()
      [[4], [3, 1], [2, 2], [1, 3]]

  Setting both `min_length` and `max_length` to the same value is equivalent to setting `length` to this value:

  Sage

      sage: Compositions(4, min_length=2, max_length=2).list()
      [[3, 1], [2, 2], [1, 3]]

  Python

      >>> from sage.all import *
      >>> Compositions(Integer(4), min_length=Integer(2), max_length=Integer(2)).list()
      [[3, 1], [2, 2], [1, 3]]

  The options `inner` and `outer` can be used to set part-by-part containment constraints. The list of compositions of 4 bounded above by `[3,1,2]` is given by:

  Sage

      sage: list(Compositions(4, outer=[3,1,2]))
      [[3, 1], [2, 1, 1], [1, 1, 2]]

  [Python]

      >>> from sage.all import *
      >>> list(Compositions(Integer(4), outer=[Integer(3),Integer(1),Integer(2)]))
      [[3, 1], [2, 1, 1], [1, 1, 2]]

  `outer` sets `max_length` to the length of its argument. Moreover, the parts of `outer` may be infinite to clear the constraint on specific parts. This is the list of compositions of 4 of length at most 3 such that the first and third parts are at most 1:

  Sage

      sage: Compositions(4, outer=[1,oo,1]).list()
      [[1, 3], [1, 2, 1]]

  Python

      >>> from sage.all import *
      >>> Compositions(Integer(4), outer=[Integer(1),oo,Integer(1)]).list()
      [[1, 3], [1, 2, 1]]

  This is the list of compositions of 4 bounded below by `[1,1,1]`:

  Sage

      sage: Compositions(4, inner=[1,1,1]).list()
      [[2, 1, 1], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]]

  [Python]

      >>> from sage.all import *
      >>> Compositions(Integer(4), inner=[Integer(1),Integer(1),Integer(1)]).list()
      [[2, 1, 1], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]]

  The options `min_slope` and `max_slope` can be used to set constraints on the slope, that is the difference `p[i+1]-p[i]` of two consecutive parts. The following is the list of weakly increasing compositions of 4:

  Sage

      sage: Compositions(4, min_slope=0).list()
      [[4], [2, 2], [1, 3], [1, 1, 2], [1, 1, 1, 1]]

  Python

      >>> from sage.all import *
      >>> Compositions(Integer(4), min_slope=Integer(0)).list()
      [[4], [2, 2], [1, 3], [1, 1, 2], [1, 1, 1, 1]]

  Here are the weakly decreasing ones:

  Sage

      sage: Compositions(4, max_slope=0).list()
      [[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]]

  [Python]

      >>> from sage.all import *
      >>> Compositions(Integer(4), max_slope=Integer(0)).list()
      [[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]]

  The following is the list of compositions of 4 such that two consecutive parts differ by at most one:

  Sage

      sage: Compositions(4, min_slope=-1, max_slope=1).list()
      [[4], [2, 2], [2, 1, 1], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]]

  Python

      >>> from sage.all import *
      >>> Compositions(Integer(4), min_slope=-Integer(1), max_slope=Integer(1)).list()
      [[4], [2, 2], [2, 1, 1], [1, 2, 1], [1, 1, 2], [1, 1, 1, 1]]

  The constraints can be combined together in all reasonable ways. This is the list of compositions of 5 of length between 2 and 4 such that the difference between consecutive parts is between -2 and 1:

  Sage

      sage: Compositions(5, max_slope=1, min_slope=-2, min_length=2, max_length=4).list()
      [[3, 2], [3, 1, 1], [2, 3], [2, 2, 1], [2, 1, 2], [2, 1, 1, 1], [1, 2, 2], [1, 2, 1, 1], [1, 1, 2, 1], [1, 1, 1, 2]]

  [Python]

      >>> from sage.all import *
      >>> Compositions(Integer(5), max_slope=Integer(1), min_slope=-Integer(2), min_length=Integer(2), max_length=Integer(4)).list()
      [[3, 2], [3, 1, 1], [2, 3], [2, 2, 1], [2, 1, 2], [2, 1, 1, 1], [1, 2, 2], [1, 2, 1, 1], [1, 1, 2, 1], [1, 1, 1, 2]]

  We can do the same thing with an outer constraint:

  Sage

      sage: Compositions(5, max_slope=1, min_slope=-2, min_length=2, max_length=4, outer=[2,5,2]).list()
      [[2, 3], [2, 2, 1], [2, 1, 2], [1, 2, 2]]

  Python

      >>> from sage.all import *
      >>> Compositions(Integer(5), max_slope=Integer(1), min_slope=-Integer(2), min_length=Integer(2), max_length=Integer(4), outer=[Integer(2),Integer(5),Integer(2)]).list()
      [[2, 3], [2, 2, 1], [2, 1, 2], [1, 2, 2]]

  However, providing incoherent constraints may yield strange results. It is up to the user to ensure that the inner and outer compositions themselves satisfy the parts and slope constraints.

  Note that setting `min_part=0` is not allowed:

  Sage

      sage: Compositions(2, length=3, min_part=0)
      Traceback (most recent call last):
      ...
      ValueError: setting min_part=0 is not allowed for Compositions

  [Python]

      >>> from sage.all import *
      >>> Compositions(Integer(2), length=Integer(3), min_part=Integer(0))
      Traceback (most recent call last):
      ...
      ValueError: setting min_part=0 is not allowed for Compositions

  Instead you must use `IntegerVectors`:

  Sage

      sage: list(IntegerVectors(2, 3))
      [[2, 0, 0], [1, 1, 0], [1, 0, 1], [0, 2, 0], [0, 1, 1], [0, 0, 2]]

  Python

      >>> from sage.all import *
      >>> list(IntegerVectors(Integer(2), Integer(3)))
      [[2, 0, 0], [1, 1, 0], [1, 0, 1], [0, 2, 0], [0, 1, 1], [0, 0, 2]]

  The generation algorithm is constant amortized time, and handled by the generic tool `IntegerListsLex`.

  Element

    alias of `Composition`

  from_code(code)

    Return the composition from its code. The code of a composition \(I\) is a list of length \(\mathrm{size}(I)\) consisting of 1s and 0s such that there is a 1 wherever a new part starts. (Exceptional case: When the composition is empty, the code is `[0]`.)

    EXAMPLES:

    Sage

        sage: Composition([4,1,2,3,5]).to_code()
        [1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
        sage: Compositions().from_code(_)
        [4, 1, 2, 3, 5]
        sage: Composition([3,1,2,3,5]).to_code()
        [1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
        sage: Compositions().from_code(_)
        [3, 1, 2, 3, 5]

    Python

        >>> from sage.all import *
        >>> Composition([Integer(4),Integer(1),Integer(2),Integer(3),Integer(5)]).to_code()
        [1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
        >>> Compositions().from_code(_)
        [4, 1, 2, 3, 5]
        >>> Composition([Integer(3),Integer(1),Integer(2),Integer(3),Integer(5)]).to_code()
        [1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0]
        >>> Compositions().from_code(_)
        [3, 1, 2, 3, 5]

  from_descents(descents, nps=None)

    Return a composition from the list of descents.

    INPUT:

    - `descents` – an iterable

    - `nps` – integer or `None` (default: `None`)

    OUTPUT:

    - The composition of `nps` whose descents are listed in `descents`, assuming that `nps` is not `None` (otherwise, the last element of `descents` is removed from `descents`, and `nps` is set to be this last element plus 1).

    EXAMPLES:

    Sage

        sage: [x-1 for x in Composition([1, 1, 3, 4, 3]).to_subset()]
        [0, 1, 4, 8]
        sage: Compositions().from_descents([1,0,4,8],12)
        [1, 1, 3, 4, 3]
        sage: Compositions().from_descents([1,0,4,8,11])
        [1, 1, 3, 4, 3]

    Python

        >>> from sage.all import *
        >>> [x-Integer(1) for x in Composition([Integer(1), Integer(1), Integer(3), Integer(4), Integer(3)]).to_subset()]
        [0, 1, 4, 8]
        >>> Compositions().from_descents([Integer(1),Integer(0),Integer(4),Integer(8)],Integer(12))
        [1, 1, 3, 4, 3]
        >>> Compositions().from_descents([Integer(1),Integer(0),Integer(4),Integer(8),Integer(11)])
        [1, 1, 3, 4, 3]

  from_subset(S, n)

    The composition of \(n\) corresponding to the subset `S` of \(\{1, 2, \ldots, n-1\}\) under the bijection that maps the composition \((i_1, i_2, \ldots, i_k)\) of \(n\) to the subset \(\{i_1, i_1 + i_2, i_1 + i_2 + i_3, \ldots, i_1 + \cdots + i_{k-1}\}\) (see `Composition.to_subset()`).

    INPUT:

    - `S` – an iterable, a subset of \(\{1, 2, \ldots, n-1\}\)

    - `n` – integer

    EXAMPLES:

    Sage

        sage: Compositions().from_subset([2,1,5,9], 12)
        [1, 1, 3, 4, 3]
        sage: Compositions().from_subset({2,1,5,9}, 12)
        [1, 1, 3, 4, 3]

        sage: Compositions().from_subset([], 12)
        [12]
        sage: Compositions().from_subset([], 0)
        []

    Python

        >>> from sage.all import *
        >>> Compositions().from_subset([Integer(2),Integer(1),Integer(5),Integer(9)], Integer(12))
        [1, 1, 3, 4, 3]
        >>> Compositions().from_subset({Integer(2),Integer(1),Integer(5),Integer(9)}, Integer(12))
        [1, 1, 3, 4, 3]

        >>> Compositions().from_subset([], Integer(12))
        [12]
        >>> Compositions().from_subset([], Integer(0))
        []

class sage.combinat.composition.Compositions_all

  Bases: `Compositions`

  Class of all compositions.

  subset(size=None)

    Return the set of compositions of the given size.

    EXAMPLES:

    Sage

        sage: C = Compositions()
        sage: C.subset(4)
        Compositions of 4
        sage: C.subset(size=3)
        Compositions of 3

    Python

        >>> from sage.all import *
        >>> C = Compositions()
        >>> C.subset(Integer(4))
        Compositions of 4
        >>> C.subset(size=Integer(3))
        Compositions of 3

  zero()

    Return the zero of the additive monoid.

    This is the empty composition.

    EXAMPLES:

    Sage

        sage: C = Compositions()
        sage: C.zero()
        []

    Python

        >>> from sage.all import *
        >>> C = Compositions()
        >>> C.zero()
        []

class sage.combinat.composition.Compositions_constraints(*args, **kwds)

  Bases: `IntegerListsLex`

class sage.combinat.composition.Compositions_n(n)

  Bases: `Compositions`

  Class of compositions of a fixed \(n\).

  cardinality()

    Return the number of compositions of \(n\).

  random_element()

    Return a random `Composition` with uniform probability.

    This method generates a random binary word starting with a 1 and then uses the bijection between compositions and their code.

    EXAMPLES:

    Sage

        sage: Compositions(5).random_element() # random
        [2, 1, 1, 1]
        sage: Compositions(0).random_element()
        []
        sage: Compositions(1).random_element()
        [1]

    Python

        >>> from sage.all import *
        >>> Compositions(Integer(5)).random_element() # random
        [2, 1, 1, 1]
        >>> Compositions(Integer(0)).random_element()
        []
        >>> Compositions(Integer(1)).random_element()
        [1]

sage.combinat.composition.composition_iterator_fast(n)

  Iterator over compositions of \(n\) yielded as lists.