devide int into lower whole ints

后端 未结 4 1842
醉话见心
醉话见心 2021-01-16 16:18

I have a random int in the range of 30-60 which I get using randint(30,60). Let\'s say it\'s 40. I want to split this number in exactly 7 random whole ints. So

4条回答
  •  离开以前
    2021-01-16 16:45

    A set of whole numbers that sum to a number n is called a partition of n; if order matters then it's called a composition.

    Here's a reasonably fast way to produce random compositions.

    import random
    
    def random_partition(n, size):
        seq = []
        while size > 1:
            x = random.randint(1, 1 + n - size)
            seq.append(x)
            n -= x
            size -= 1
        seq.append(n)
        return seq
    
    n = 40 
    for _ in range(20):
        print(random_partition(n, 7))
    

    typical output

    [26, 2, 8, 1, 1, 1, 1]
    [30, 2, 1, 3, 1, 1, 2]
    [26, 5, 3, 1, 2, 2, 1]
    [2, 25, 9, 1, 1, 1, 1]
    [28, 2, 2, 2, 1, 2, 3]
    [23, 1, 9, 3, 2, 1, 1]
    [3, 26, 1, 7, 1, 1, 1]
    [25, 1, 7, 1, 2, 1, 3]
    [10, 8, 11, 5, 3, 1, 2]
    [19, 16, 1, 1, 1, 1, 1]
    [12, 23, 1, 1, 1, 1, 1]
    [1, 14, 15, 7, 1, 1, 1]
    [29, 5, 1, 1, 2, 1, 1]
    [25, 1, 3, 3, 1, 2, 5]
    [10, 12, 10, 4, 1, 2, 1]
    [13, 4, 6, 14, 1, 1, 1]
    [31, 3, 1, 1, 1, 1, 2]
    [16, 11, 9, 1, 1, 1, 1]
    [3, 26, 5, 3, 1, 1, 1]
    [31, 2, 1, 2, 2, 1, 1]
    

    We use 1 + n - size as the upper limit because the other size - 1 numbers are at least 1.

    Here's a fairly efficient way to generate all partitions of a given integer. Note that these are ordered; you could use random.shuffle if you want to produce random compositions from these partitions.

    We first print all partitions of 16 of size 5, and then we count the number of partitions of 40 of size 7 (= 2738).

    This code was derived from an algorithm by Jerome Kelleher.

    def partitionR(num, size):
        a = [0, num] + [0] * (num - 1)
        size -= 1
        k = 1
        while k > 0:
            x = a[k - 1] + 1
            y = a[k] - 1
            k -= 1
            while x <= y and k < size:
                a[k] = x
                y -= x
                k += 1
            a[k] = x + y
            if k == size:
                yield a[:k + 1]
    
    for u in partitionR(16, 5):
        print(u)
    
    print('- ' * 32)
    print(sum(1 for _ in partitionR(40, 7)))
    

    output

    [1, 1, 1, 1, 12]
    [1, 1, 1, 2, 11]
    [1, 1, 1, 3, 10]
    [1, 1, 1, 4, 9]
    [1, 1, 1, 5, 8]
    [1, 1, 1, 6, 7]
    [1, 1, 2, 2, 10]
    [1, 1, 2, 3, 9]
    [1, 1, 2, 4, 8]
    [1, 1, 2, 5, 7]
    [1, 1, 2, 6, 6]
    [1, 1, 3, 3, 8]
    [1, 1, 3, 4, 7]
    [1, 1, 3, 5, 6]
    [1, 1, 4, 4, 6]
    [1, 1, 4, 5, 5]
    [1, 2, 2, 2, 9]
    [1, 2, 2, 3, 8]
    [1, 2, 2, 4, 7]
    [1, 2, 2, 5, 6]
    [1, 2, 3, 3, 7]
    [1, 2, 3, 4, 6]
    [1, 2, 3, 5, 5]
    [1, 2, 4, 4, 5]
    [1, 3, 3, 3, 6]
    [1, 3, 3, 4, 5]
    [1, 3, 4, 4, 4]
    [2, 2, 2, 2, 8]
    [2, 2, 2, 3, 7]
    [2, 2, 2, 4, 6]
    [2, 2, 2, 5, 5]
    [2, 2, 3, 3, 6]
    [2, 2, 3, 4, 5]
    [2, 2, 4, 4, 4]
    [2, 3, 3, 3, 5]
    [2, 3, 3, 4, 4]
    [3, 3, 3, 3, 4]
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
    2738
    

提交回复
热议问题