def yield_all_compositions_of_integer(n):
    """
    Yields all compositions of positive integer ``n``.

    ..  container:: example

        >>> for tuple_ in abjad.mathtools.yield_all_compositions_of_integer(5):
        ...     tuple_
        ...
        (5,)
        (4, 1)
        (3, 2)
        (3, 1, 1)
        (2, 3)
        (2, 2, 1)
        (2, 1, 2)
        (2, 1, 1, 1)
        (1, 4)
        (1, 3, 1)
        (1, 2, 2)
        (1, 2, 1, 1)
        (1, 1, 3)
        (1, 1, 2, 1)
        (1, 1, 1, 2)
        (1, 1, 1, 1, 1)

    Lists parts in descending lex order.

    Parts sum to ``n``.

    Finds small values of ``n`` easily.

    Takes around 4 seconds for ``n`` equal to 17.

    Returns integer tuple generator.
    """
    from abjad import mathtools

    compositions = []
    integer = 0
    string_length = n
    while integer < 2 ** (n - 1):
        binary_string = mathtools.integer_to_binary_string(integer)
        binary_string = binary_string.zfill(string_length)
        digits = [int(_) for _ in list(binary_string)]
        partition = []
        generator = itertools.groupby(digits, lambda _: _)
        for value, group in generator:
            partition.append(list(group))
        sublengths = [len(part) for part in partition]
        composition = tuple(sublengths)
        compositions.append(composition)
        integer += 1
    for composition in reversed(sorted(compositions)):
        yield composition
def yield_all_compositions_of_integer(n):
    """
    Yields all compositions of positive integer ``n``.

    ..  container:: example

        >>> for tuple_ in abjad.mathtools.yield_all_compositions_of_integer(5):
        ...     tuple_
        ...
        (5,)
        (4, 1)
        (3, 2)
        (3, 1, 1)
        (2, 3)
        (2, 2, 1)
        (2, 1, 2)
        (2, 1, 1, 1)
        (1, 4)
        (1, 3, 1)
        (1, 2, 2)
        (1, 2, 1, 1)
        (1, 1, 3)
        (1, 1, 2, 1)
        (1, 1, 1, 2)
        (1, 1, 1, 1, 1)

    Lists parts in descending lex order.

    Parts sum to ``n``.

    Finds small values of ``n`` easily.

    Takes around 4 seconds for ``n`` equal to 17.

    Returns integer tuple generator.
    """
    from abjad import mathtools
    compositions = []
    integer = 0
    string_length = n
    while integer < 2**(n - 1):
        binary_string = mathtools.integer_to_binary_string(integer)
        binary_string = binary_string.zfill(string_length)
        digits = [int(_) for _ in list(binary_string)]
        partition = []
        generator = itertools.groupby(digits, lambda _: _)
        for value, group in generator:
            partition.append(list(group))
        sublengths = [len(part) for part in partition]
        composition = tuple(sublengths)
        compositions.append(composition)
        integer += 1
    for composition in reversed(sorted(compositions)):
        yield composition
Exemple #3
0
    def dot_count(self):
        r"""
        Gets dot count.

        ..  container:: example

            Gets dot count:

            >>> for n in range(1, 16 + 1):
            ...     try:
            ...         duration = abjad.Duration(n, 16)
            ...         sixteenths = duration.with_denominator(16)
            ...         dot_count = duration.dot_count
            ...         string = f'{sixteenths!s}\t{dot_count}'
            ...         print(string)
            ...     except abjad.AssignabilityError:
            ...         sixteenths = duration.with_denominator(16)
            ...         print(f'{sixteenths!s}\t--')
            ...
            1/16    0
            2/16    0
            3/16    1
            4/16    0
            5/16    --
            6/16    1
            7/16    2
            8/16    0
            9/16    --
            10/16   --
            11/16   --
            12/16   1
            13/16   --
            14/16   2
            15/16   3
            16/16   0

        Dot count defined equal to number of dots required to notate duration.

        Raises assignability error when duration is not assignable.

        Returns positive integer.
        """
        if not self.is_assignable:
            raise exceptions.AssignabilityError
        binary_string = mathtools.integer_to_binary_string(self.numerator)
        digit_sum = sum([int(x) for x in list(binary_string)])
        dot_count = digit_sum - 1
        return dot_count
Exemple #4
0
    def yield_partitions(self):
        """
        Yields partitions of sequence.

        ..  container:: example

            >>> enumerator = abjad.Enumerator([0, 1, 2])
            >>> for partition in enumerator.yield_partitions():
            ...     partition
            ...
            Sequence([Sequence([0, 1, 2])])
            Sequence([Sequence([0, 1]), Sequence([2])])
            Sequence([Sequence([0]), Sequence([1, 2])])
            Sequence([Sequence([0]), Sequence([1]), Sequence([2])])

        ..  container:: example

            >>> enumerator = abjad.Enumerator([0, 1, 2, 3])
            >>> for partition in enumerator.yield_partitions():
            ...     partition
            ...
            Sequence([Sequence([0, 1, 2, 3])])
            Sequence([Sequence([0, 1, 2]), Sequence([3])])
            Sequence([Sequence([0, 1]), Sequence([2, 3])])
            Sequence([Sequence([0, 1]), Sequence([2]), Sequence([3])])
            Sequence([Sequence([0]), Sequence([1, 2, 3])])
            Sequence([Sequence([0]), Sequence([1, 2]), Sequence([3])])
            Sequence([Sequence([0]), Sequence([1]), Sequence([2, 3])])
            Sequence([Sequence([0]), Sequence([1]), Sequence([2]), Sequence([3])])

        Returns generator of nested sequences.
        """
        length = len(self.sequence) - 1
        for i in range(2 ** length):
            binary_string = mathtools.integer_to_binary_string(i)
            binary_string = binary_string.zfill(length)
            part = list(self.sequence[0:1])
            partition = [part]
            for n, token in zip(self.sequence[1:], binary_string):
                if int(token) == 0:
                    part.append(n)
                else:
                    part = [n]
                    partition.append(part)
            parts = [Sequence(items=_) for _ in partition]
            partition = Sequence(items=parts)
            yield partition
Exemple #5
0
    def dot_count(self) -> int:
        r"""
        Gets dot count.

        ..  container:: example

            Gets dot count:

            >>> for n in range(1, 16 + 1):
            ...     try:
            ...         duration = abjad.Duration(n, 16)
            ...         sixteenths = duration.with_denominator(16)
            ...         dot_count = duration.dot_count
            ...         string = f'{sixteenths!s}\t{dot_count}'
            ...         print(string)
            ...     except abjad.AssignabilityError:
            ...         sixteenths = duration.with_denominator(16)
            ...         print(f'{sixteenths!s}\t--')
            ...
            1/16    0
            2/16    0
            3/16    1
            4/16    0
            5/16    --
            6/16    1
            7/16    2
            8/16    0
            9/16    --
            10/16   --
            11/16   --
            12/16   1
            13/16   --
            14/16   2
            15/16   3
            16/16   0

        Dot count defined equal to number of dots required to notate duration.

        Raises assignability error when duration is not assignable.
        """
        if not self.is_assignable:
            raise exceptions.AssignabilityError
        binary_string = mathtools.integer_to_binary_string(self.numerator)
        digit_sum = sum([int(x) for x in list(binary_string)])
        dot_count = digit_sum - 1
        return dot_count
Exemple #6
0
def is_assignable_integer(argument):
    r"""
    Is true when ``argument`` is equivalent to an integer that can be written
    without recourse to ties.

    ..  container:: example

        >>> for n in range(0, 16 + 1):
        ...     print('%s\t%s' % (n, abjad.mathtools.is_assignable_integer(n)))
        ...
        0  False
        1  True
        2  True
        3  True
        4  True
        5  False
        6  True
        7  True
        8  True
        9  False
        10 False
        11 False
        12 True
        13 False
        14 True
        15 True
        16 True

    Returns true or false.
    """
    from abjad import mathtools

    if isinstance(argument, int):
        if 0 < argument:
            if "01" not in mathtools.integer_to_binary_string(argument):
                return True
    return False
Exemple #7
0
def is_assignable_integer(argument):
    r"""
    Is true when ``argument`` is equivalent to an integer that can be written
    without recourse to ties.

    ..  container:: example

        >>> for n in range(0, 16 + 1):
        ...     print('%s\t%s' % (n, abjad.mathtools.is_assignable_integer(n)))
        ...
        0  False
        1  True
        2  True
        3  True
        4  True
        5  False
        6  True
        7  True
        8  True
        9  False
        10 False
        11 False
        12 True
        13 False
        14 True
        15 True
        16 True

    Returns true or false.
    """
    from abjad import mathtools
    if isinstance(argument, int):
        if 0 < argument:
            if '01' not in mathtools.integer_to_binary_string(argument):
                return True
    return False
Exemple #8
0
    def yield_combinations(self, minimum_length=None, maximum_length=None):
        """
        Yields combinations of sequence items.

        ..  container:: example

            >>> enumerator = abjad.Enumerator([1, 2, 3, 4])
            >>> for combination in enumerator.yield_combinations():
            ...     combination
            Sequence([])
            Sequence([1])
            Sequence([2])
            Sequence([1, 2])
            Sequence([3])
            Sequence([1, 3])
            Sequence([2, 3])
            Sequence([1, 2, 3])
            Sequence([4])
            Sequence([1, 4])
            Sequence([2, 4])
            Sequence([1, 2, 4])
            Sequence([3, 4])
            Sequence([1, 3, 4])
            Sequence([2, 3, 4])
            Sequence([1, 2, 3, 4])

        ..  container:: example

            >>> enumerator = abjad.Enumerator([1, 2, 3, 4])
            >>> for combination in enumerator.yield_combinations(
            ...     minimum_length=3,
            ...     ):
            ...     combination
            Sequence([1, 2, 3])
            Sequence([1, 2, 4])
            Sequence([1, 3, 4])
            Sequence([2, 3, 4])
            Sequence([1, 2, 3, 4])

        ..  container:: example

            >>> enumerator = abjad.Enumerator([1, 2, 3, 4])
            >>> for combination in enumerator.yield_combinations(
            ...     maximum_length=2,
            ...     ):
            ...     combination
            Sequence([])
            Sequence([1])
            Sequence([2])
            Sequence([1, 2])
            Sequence([3])
            Sequence([1, 3])
            Sequence([2, 3])
            Sequence([4])
            Sequence([1, 4])
            Sequence([2, 4])
            Sequence([3, 4])

        ..  container:: example

            >>> enumerator = abjad.Enumerator([1, 2, 3, 4])
            >>> for combination in enumerator.yield_combinations(
            ...     minimum_length=2,
            ...     maximum_length=2,
            ...     ):
            ...     combination
            Sequence([1, 2])
            Sequence([1, 3])
            Sequence([2, 3])
            Sequence([1, 4])
            Sequence([2, 4])
            Sequence([3, 4])

        ..  container:: example

            >>> enumerator = abjad.Enumerator('text')
            >>> for combination in enumerator.yield_combinations():
            ...     ''.join([str(_) for _ in combination])
            ''
            't'
            'e'
            'te'
            'x'
            'tx'
            'ex'
            'tex'
            't'
            'tt'
            'et'
            'tet'
            'xt'
            'txt'
            'ext'
            'text'

        Yields combinations in binary string order.

        Returns sequence generator.
        """
        length = len(self.sequence)
        for i in range(2 ** length):
            binary_string = mathtools.integer_to_binary_string(i)
            binary_string = binary_string.zfill(length)
            sublist = []
            for j, digit in enumerate(reversed(binary_string)):
                if digit == "1":
                    sublist.append(self.sequence[j])
            yield_sublist = True
            if minimum_length is not None:
                if len(sublist) < minimum_length:
                    yield_sublist = False
            if maximum_length is not None:
                if maximum_length < len(sublist):
                    yield_sublist = False
            if yield_sublist:
                if isinstance(self.sequence, str):
                    yield "".join(sublist)
                else:
                    yield Sequence(items=sublist)
def partition_integer_into_canonic_parts(n, decrease_parts_monotonically=True):
    """
    Partitions integer ``n`` into canonic parts.

    ..  container:: example

        Returns all parts positive on positive ``n``:

        >>> for n in range(1, 11):
        ...     print(n, abjad.mathtools.partition_integer_into_canonic_parts(n))
        ...
        1 (1,)
        2 (2,)
        3 (3,)
        4 (4,)
        5 (4, 1)
        6 (6,)
        7 (7,)
        8 (8,)
        9 (8, 1)
        10 (8, 2)

    ..  container:: example

        Returns all parts negative on negative ``n``:

        >>> for n in reversed(range(-20, -10)):
        ...     print(n, abjad.mathtools.partition_integer_into_canonic_parts(n))
        ...
        -11 (-8, -3)
        -12 (-12,)
        -13 (-12, -1)
        -14 (-14,)
        -15 (-15,)
        -16 (-16,)
        -17 (-16, -1)
        -18 (-16, -2)
        -19 (-16, -3)
        -20 (-16, -4)

    ..  container:: example

        Returns parts that increase monotonically:

        >>> for n in range(11, 21):
        ...     print(n, abjad.mathtools.partition_integer_into_canonic_parts(n,
        ...         decrease_parts_monotonically=False))
        ...
        11 (3, 8)
        12 (12,)
        13 (1, 12)
        14 (14,)
        15 (15,)
        16 (16,)
        17 (1, 16)
        18 (2, 16)
        19 (3, 16)
        20 (4, 16)

    Returns tuple with parts that decrease monotonically.

    Returns tuple of integers.
    """
    from abjad import mathtools

    assert isinstance(n, int), repr(n)
    assert isinstance(decrease_parts_monotonically, bool)
    if n == 0:
        return (0,)
    result = []
    previous_empty = True
    binary_n = mathtools.integer_to_binary_string(abs(n))
    binary_length = len(binary_n)
    for i, character in enumerate(binary_n):
        if character == "1":
            place_value = 2 ** (binary_length - i - 1)
            if previous_empty:
                result.append(place_value)
            else:
                result[-1] += place_value
            previous_empty = False
        else:
            previous_empty = True
    sign_n = mathtools.sign(n)
    if mathtools.sign(n) == -1:
        result = [sign_n * _ for _ in result]
    if decrease_parts_monotonically:
        return tuple(result)
    else:
        return tuple(reversed(result))
Exemple #10
0
def partition_integer_into_canonic_parts(n, decrease_parts_monotonically=True):
    """
    Partitions integer ``n`` into canonic parts.

    ..  container:: example

        Returns all parts positive on positive ``n``:

        >>> for n in range(1, 11):
        ...     print(n, abjad.mathtools.partition_integer_into_canonic_parts(n))
        ...
        1 (1,)
        2 (2,)
        3 (3,)
        4 (4,)
        5 (4, 1)
        6 (6,)
        7 (7,)
        8 (8,)
        9 (8, 1)
        10 (8, 2)

    ..  container:: example

        Returns all parts negative on negative ``n``:

        >>> for n in reversed(range(-20, -10)):
        ...     print(n, abjad.mathtools.partition_integer_into_canonic_parts(n))
        ...
        -11 (-8, -3)
        -12 (-12,)
        -13 (-12, -1)
        -14 (-14,)
        -15 (-15,)
        -16 (-16,)
        -17 (-16, -1)
        -18 (-16, -2)
        -19 (-16, -3)
        -20 (-16, -4)

    ..  container:: example

        Returns parts that increase monotonically:

        >>> for n in range(11, 21):
        ...     print(n, abjad.mathtools.partition_integer_into_canonic_parts(n,
        ...         decrease_parts_monotonically=False))
        ...
        11 (3, 8)
        12 (12,)
        13 (1, 12)
        14 (14,)
        15 (15,)
        16 (16,)
        17 (1, 16)
        18 (2, 16)
        19 (3, 16)
        20 (4, 16)

    Returns tuple with parts that decrease monotonically.

    Returns tuple of integers.
    """
    from abjad import mathtools
    assert isinstance(n, int), repr(n)
    assert isinstance(decrease_parts_monotonically, bool)
    if n == 0:
        return (0, )
    result = []
    previous_empty = True
    binary_n = mathtools.integer_to_binary_string(abs(n))
    binary_length = len(binary_n)
    for i, character in enumerate(binary_n):
        if character == '1':
            place_value = 2**(binary_length - i - 1)
            if previous_empty:
                result.append(place_value)
            else:
                result[-1] += place_value
            previous_empty = False
        else:
            previous_empty = True
    sign_n = mathtools.sign(n)
    if mathtools.sign(n) == -1:
        result = [sign_n * _ for _ in result]
    if decrease_parts_monotonically:
        return tuple(result)
    else:
        return tuple(reversed(result))