I have a fairly basic math problem in Python & I dont know where to look.
Explanation:
My only requirements are the following:
from random import randint, shuffle
def divide_number(number, parts_number, allow_zero = False ):
if (parts_number > number):
raise ValueError("Number of parts can't be higher than the number");
parts = {currency: []}
number_rest = number
for i in range(1, parts_number + 1):
if (i == parts_number):
parts[currency].append(number_rest)
break
else:
new_number = randint(0, number_rest) if allow_zero else randint(1, (number_rest -
(parts_number - i)) // 2)
number_rest -= new_number
parts[currency].append(new_number)
return parts
Running the function:
divide_number(100, 10)
Output
[2, 37, 8, 10, 2, 4, 4, 4, 26, 3]
This piece of code I've found online seems to work just great but it doesn't meet my requirements. How do I alter it so it does meet my requirements regarding min and max values?
So basicly, I want to go from unfair distribution to fair distribution.
Is is not easy to make rather fair distribution with limits.
For reasonable sum and parts (p
) values we can make p cells (friend pockets) and randomly put coin by coin into them (if possible)
import random
def randparts(summ, p, minn, maxx):
maxx = maxx - minn
summ -= p * minn
if summ < 0:
return None
if p * maxx >= summ * 2:
lst = [0] * p
while summ > 0:
r = random.randrange(p)
if lst[r] < maxx:
summ -= 1
lst[r] += 1
else:
lst = [maxx] * p
summ = maxx * p - summ
while summ > 0:
r = random.randrange(p)
if lst[r] > 0:
summ -= 1
lst[r] -= 1
for i in range(len(lst)):
lst[i] += minn
return lst
print(randparts(100, 10, 5, 40))
>>>[7, 17, 8, 10, 8, 8, 9, 12, 10, 11]
More concise and pythonic version from the comment of Olvin Roght (also removed the second branch for optimization for large summ
values)
def randparts(number, divider, min_value, max_value):
sum_min = divider * min_value
if sum_min > number:
return
number -= sum_min
result = [min_value] * divider
while number:
pocket = randrange(divider)
if result[pocket] <= max_value:
result[pocket] += 1
number -= 1
return result