DEV Community

J. Marchán
J. Marchán

Posted on

3 2

Unequally distributed quantity

Suppose that you have to divide or to distribute a quantity in three (maybe a rent payment), but you want to do it unequally.

It can be done more or less mentally, but I wanted to have
quickly all the possibilities and decided to write some code to do it.

I though how it is done mentally. For instance, dividing 990 units in 3 parts:

  1. You have three parts of 330 each one
  2. Subtract 5 to one and add it to another
  3. Repeating that you obtain different possibilities to divide initial quantity

Translation to code.

First approximation to the problem was to establish a minimum that each person would pay. Let’s to say 250. 250×3= 750, so it remained 240 units to share out.

I wanted a granularity of 5 units, so there was in fact a 24/5=48 items (of 5 units) to share out.

It was not trivial for me to lay out the problem until I realized that this matched with some well known combinatorial problem that I didn’t remember. After a search I found exactly what I was looking for: Start and bars
It can be used to solve many simple counting problems, such as how many ways there are to put n indistinguishable balls into k distinguishable bins.

It can be easily done with Python using combinations function

 import itertools

def combinations(n, k):
    return itertools.combinations(range(n), k)

def calculate_rent(n, k):
    for c in combinations(n, k):
        if sum(c)==n:
            yield c

combinations(n,k) return r length subsequences of elements from the input iterable n. Afterwards, we only want subsequences whose sum of the k bins be equal to n.

Just left to write some auxiliary code in order to print the list. Due to what we have obtained is a list of ways to put n indistinguishable balls (48) into k distinguishable bins (3), it is necessary to multiply each ball by our granularity (5) and sum the minimum.

total = 990
minimum = 250
people = 3
granularity = 5
remain = total - minimum*people
rent_combinations = calculate_rent(remain/granularity,people)
for rents in rent_combinations:
    print([5*i+minimum for i in rents])

Below is displayed a partial screen-shot of the 192 total elements of the output.

Output

Original post in myram

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay