2

Let's say I have an integer 50. I'm trying to split this into a random number of parts so that the sum of each part form 50 again. E.g, if I split it in 4 parts: 20 + 10 + 15 + 5 = 50.

The number of parts (always less than the total amount) will have to be randomly generated and provided. How can I achieve this?

blankface
  • 5,757
  • 19
  • 67
  • 114
  • Related, except the number of parts is fixed rather than random: https://stackoverflow.com/questions/61393463/is-there-an-efficient-way-to-generate-n-random-integers-in-a-range-that-have-a-g – Peter O. Jun 16 '21 at 08:50

2 Answers2

2

python code:

def split_num():
    n = 50
    parts = random.randint(1,n)
    result = []
    for i in range(parts-1):
        x = random.randint(1,n-parts+i+1)
        n = n - x
        result.append(x)
    result.append(n)
    print(result)
    print(sum(result))

import random
split_num()

result:

[4, 33, 4, 1, 8]
50
leaf_yakitori
  • 2,232
  • 1
  • 9
  • 21
  • This does not take into consideration that the number of parts (which is randomly generated) is provided. In your solution it's determined based on the loop. I've updated my question with some more context around that. – blankface Jun 16 '21 at 08:01
1
from random import *


def break_num2(num, count, mode="int"):
    if mode == "float":
        ingreds = [num / count for _ in range(count)]
    elif mode == "int":
        ingreds = [num // count for _ in range(count)]
    while count:
        i1 = randrange(len(ingreds))
        i2 = (i1 + 1) % len(ingreds)
        if mode == "float":
            n = uniform(0, ingreds[i1])
        elif mode == "int":
            n = randint(0, ingreds[i1])
        ingreds[i1] -= n
        ingreds[i2] += n
        count -= 1
    if sum(ingreds) < num:
        ingreds.append(num - sum(ingreds))
    return ingreds

x = break_num2(50, 4)
y = break_num2(50, 4, "float")
print(x, sum(x), y, sum(y))

This prints for instance:

[12, 3, 4, 29, 2] 50 [0.8403666071897256, 36.636786293337956, 12.5, 0.02284709947231712] 50.0

Student
  • 708
  • 4
  • 11