How to generate a certain number of random whole numbers that add up to a certain number and are at least a certain number or more?

Viewed 109

I want to generate 10 whole numbers that add up to 40 and are in the range of 2-6.

For example:

2 + 6 + 2 + 5 + 6 + 2 + 2 + 6 + 3 + 6 = 40

Ten random numbers between 2 and 6 that add up to 40.

6 Answers

Given the relatively small search space, you could use itertools.combinations_with_replacement() to generate all possible sequences of 10 numbers between 2 and 6, save the ones that sum to 40 - then pick and shuffle one at random when requested:

from itertools import combinations_with_replacement as combine
from random import choice, shuffle

sequences = [list(combo) for combo in combine(range(2, 6+1), 10) if sum(combo) == 40]

def get_random_sequence_of_sum_40():
    seq = choice(sequences)
    shuffle(seq)
    return seq

# ... later when you need random sequences of sum=40
for i in range(10):
    rand_sequence = get_random_sequence_of_sum_40()
    print(f"The sum of {rand_sequence} is {sum(rand_sequence)}")

Sample output:

The sum of [6, 3, 4, 4, 3, 3, 4, 6, 5, 2] is 40
The sum of [3, 3, 5, 3, 5, 5, 3, 3, 5, 5] is 40
The sum of [3, 3, 6, 3, 4, 6, 3, 4, 4, 4] is 40
The sum of [6, 6, 5, 3, 4, 3, 3, 2, 4, 4] is 40
The sum of [5, 2, 2, 4, 4, 4, 5, 4, 4, 6] is 40
The sum of [4, 4, 4, 3, 4, 4, 3, 6, 4, 4] is 40
The sum of [4, 4, 5, 4, 2, 4, 4, 5, 5, 3] is 40
The sum of [4, 2, 6, 2, 5, 6, 2, 5, 4, 4] is 40
The sum of [3, 6, 3, 4, 3, 3, 4, 4, 6, 4] is 40
The sum of [2, 2, 6, 2, 3, 5, 6, 4, 4, 6] is 40

My idea is to generate numbers in the range of [2,6] until the length of the list is 10 then start checking the sum, if it's not 40 then remove the first element of the list and generate a new number. The only problem is that you might need to check if it's even possible to sum the numbers to your target number, for example it can never reach the target number if it's odd but all the generated numbers are even.

import random

low,high = 2,6
count = 10
target = 40

k = []
r = range(low,high+1)
tries = 0
while True:
    k.append(random.choice(r))
    if len(k) == count:
        if sum(k) == target:
            break
        k = k[1:]
        tries += 1
        
print(k)
print(len(k))
print(sum(k))
print(tries)

If I understand your question correct this should do it:

import random as rd

run = True
while run:
    list = []
    for i in range(10):
        ran_num = rd.randint(2, 6)
        list.append(ran_num)
        if sum(list) >= 40 and len(list) == 10:
            print(list)
            run = False  

This will print out a list of 10 numbers that add up to 40 or more.

The main problem I would say is how you define your randomness of numbers.

import random

wanted_sum = 40
number_of_numbers = 10

min_number = 2
max_number = 6

if number_of_numbers * min_number > wanted_sum or number_of_numbers * max_number < wanted_sum:
    print("not possible")
else:
    to_distribute = wanted_sum - min_number * number_of_numbers
    
    print_list = [min_number for i in range(number_of_numbers)]
    while True:
        for i in range(number_of_numbers):
            if print_list[i] < max_number:
                if random.uniform(0, 1) >= 0.5:
                    print_list[i] += 1
                    to_distribute -= 1
            if to_distribute == 0:
                break
        if to_distribute == 0:
            break
    print(print_list, sum(print_list))

I know that I am beginner and my answer is not a perfect one but the code actually works:

from random import randint
result = 0
while result != 40:
    a, b, c, d, e = randint(2,6), randint(2,6), randint(2,6), randint(2,6), randint(2,6)
    f, g, h, i, j = randint(2,6), randint(2,6), randint(2,6), randint(2,6), randint(2,6)
    result = a+b+c+d+e+f+g+h+i+j
a,b,c,d,e,f,g,h,i,j,x = str(a), str(b), str(c), str(d), str(e), str(f), str(g), str(h), str(i), str(j), '+'
print(a,x,b,x,c,x,d,x,e,x,f,x,g,x,h,x,i,x,j,x,'=',result)

Here I would like to bring one more thing, if you just repeat the range values until the size. like 2,3,4..6 and again start from 2,3.. until the list size will be 10.

for this question we can get answer too.

l = [*range(2, 6+1, 1)]
for i in range(0, 10-len(l)):
    if l[-1] == 6: 
        l.insert(len(l), 2)
    else:
        l.insert(len(l), l[-1]+1)

Output:

l
[2, 3, 4, 5, 6, 2, 3, 4, 5, 6]

sum(l)
40

I also apply the same rule with range 2-6 list size 15 where I want answer 60.

Related