Last active
April 21, 2024 11:08
-
-
Save VehpuS/70bf146768f36f1035d78cdc8729d37f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def partition (count, total, steps=1, minimum=0, maximum=None, sum_total=True): | |
''' | |
@summary: | |
Given a number "total" and number of parts to split it to "count", return a count-length tuple made of numbers that sum up to "total". | |
Steps defines in what increments to increase each "bin", starting with 0 or minimum sized bins to bins of size total or maximum. | |
If sum total is True - only partitions summing to total will return, otherwise, partitions with lower sums will be returned as well. | |
@param count: | |
How many bins to split total into. | |
@param total: | |
The total size to split into bins. | |
@param steps: | |
In what increments to increase the size of the bins. | |
i.e. if minimum = 1 and steps = 2, bin sizes will be 1, 3, 5,... | |
@param minimum: | |
The minimum size of each bin. | |
@param maximum: | |
The maximum size of each bin. If not passed, it will default to the total. | |
@param sum_total: | |
If True, only partitions that sum to total will return, otherwise any partitions whose sum is lower than total will be returned. | |
@notes: | |
Based on https://stackoverflow.com/questions/41837444/how-to-find-all-ways-to-obtain-an-integer-n-as-the-sum-of-m-integers-without-or | |
''' | |
start = minimum | |
maximum = total if (maximum is None or total < maximum) else maximum | |
if 0 == count: | |
yield tuple([]) | |
else: | |
while (start <= total and | |
start <= maximum and | |
total <= count * maximum and | |
total >= count * minimum): | |
for part in partition(count - 1, total - start, steps, minimum, maximum, sum_total): | |
res = part + (start,) | |
if (not sum_total or len(res) != count or total == sum(res)): | |
yield res | |
start = start + steps |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment