Debt settlement after general expenses efficiently: max. 1 transaction per person

Context

I am creating a program to facilitate sharing costs between people. Consumption:

  • payer who originally paid expenses
  • a certain number of depositors who will pay part of the costs (note that the payer is also a depositor).

The shares that depositors must pay for a certain expense need not be equal. After some arbitrary amount of expenses, some people will owe money, while other people will owe money.

Problem

The problem is to find an easy way for all people to pay off their debts. Instead of some people having to pay several others, and some people not having to pay anyone at all, I want one person to have to pay the most. In addition, I would like to minimize the excess amount of money that a person receives beyond what he or she actually owes. For example, if you owe $ 100, you really do not want to receive $ 2000 and you must redirect $ 1900 to someone else.

Model

Every person has a duty. Debt:

  • positive if a person owes money
  • negative if a person owes money.
  • zero if none of the above

So, the model consists of a set of numbers representing debts.

This is a zero-sum situation: the amount of money that people owe is equal to the amount of money that people bring (credit without a lender is impossible). This means that no matter who receives the payment, if everyone at the end paid what they owed, no one should have any money.

Anna pays Bob $ 100. If Anna had a debt of 100, her debt is now 0. If Bob had a debt of -100, his debt is also 0. In the model, a money transaction is equivalent to deducting from the payer's debt and adding the same amount to the recipient.

To minimize the excess money received by the recipient in the transaction, I think that this is enough to add the largest positive debt to the largest negative debt for each transaction.

Implementation

I am considering using the minimum heap for negative debts and the maximum heap for positive debts. Then repeatedly execute the transaction from the largest in max to the smallest in minutes. This can be done by increasing the min key by the value max and removing max. If the debt is zero, remove it from the heap.

pseudo code

Let max be the largest element of maxHeap and min smallest element of minHeap . max.person and min.person is a person who has debt max and min respectively.

 while(not done) do: new transaction.from(max.person).to(min.person) if(max + min = 0) then: //remove both maxHeap.removeMax minHeap.removeMin else if (max + min < 0) then: //keep in minHeap minHeap.increaseKey(min).by(max) maxHeap.removeMax else //move min to maxHeap maxHeap.decreaseKey(max).by(|min|) 

This should give me O (nlogn) runtime if I'm not mistaken.

Question

Am I reasoning correctly? Will my decision give good results in accordance with the description of my problem? Does anyone else have a faster and / or simpler solution that still upholds the criteria for as much excess money as possible?

Note: In case it matters, I'm going to implement it in Java

EDIT: I found another pretty similar question: The sharing / costing algorithm between the group . However, this does not solve my problem, since I have criteria for the maximum transaction for each person.

+6
source share
1 answer

I edited the answer to also satisfy the situation when one recipient can receive money from several persons , and not only from one. Look down.


An interesting problem - I had to code it. Pseudo and data here, as done with Dyalog APL .

Often the only way to ensure optimality is to use brute force. For your problem, this works well when the number of participants is about 12 or less:

 ┌──┬──┬──┬──┬───┬───┬─────┬──────┬───────┬─────────┬──────────┬───────────┬─────────────┬──────────────┬─────────────────┐ │!1│!2│!3│!4│!5 │!6 │!7 │!8 │!9 │!10 │!11 │!12 │!13 │!14 │!15 │ ├──┌──┌──┌──┌───┌───┌─────┌──────┌───────┌─────────┌──────────┌───────────┌─────────────┌──────────────┌────────────────── │1 │2 │6 │24│120│720│5,040│40,320│362,880│3,628,800│39,916,800│479,001,600│6,227,020,800│87,178,291,200│1,307,674,368,000│ └──┮──┮──┮──┮───┮───┮─────┮──────┮───────┮─────────┮──────────┮───────────┮─────────────┮──────────────┮─────────────────┘ 

As we can see, the factorial of numbers is growing rapidly. If there are 10 participants, then all the same reasonable 3.6 million, 12 guys already make up 1/2 billion. You probably shouldn't think about that anymore.

If, however, we are talking about small enough gangs, it’s trivial to calculate (with the exception of one).

You set this condition:

The shares that depositors must pay for a certain expense need not be equal.

This does not change the calculation itself, but I leave out of this answer how the shares were concluded. You must have a way to determine what belongs to whom. It is essential for the calculation here that the amounts of what must be paid and what was paid are equal .

Consider the following example:

We have 4 guys who consumed 400 bucks. One guy paid for it, and they decided to share the cost equally:

 ┌──────────┬───┬───┬───┬───┬─────┐ │Guy │1 │2 │3 │4 │Total│ ├──────────┌───┌───┌───┌───┌────── │Should pay│100│100│100│100│400 │ ├──────────┌───┌───┌───┌───┌────── │Payed │0 │0 │0 │400│400 │ └──────────┮───┮───┮───┮───┮─────┘ 

Since guy number 1 paid 0, he apparently needs to pay an extra 100, etc. This is a simple case. Only decision:

  1 solutions with unique transfer sums. Best solution: ┌─────────────────────────┬──────┬──────┬──────┬──────┬─────┬────────┐ │Guy # │1 │2 │3 │4 │Total│Turnover│ ├─────────────────────────┌──────┌──────┌──────┌──────┌─────┌───────── │Should pay │100 │100 │100 │100 │400 │ │ ├─────────────────────────┌──────┌──────┌──────┌──────┌─────┌───────── │Has paid │0 │0 │0 │400 │400 │ │ ├─────────────────────────┌──────┌──────┌──────┌──────┌─────┌───────── │Gets from the one to left│0.00 │100.00│200.00│300.00│ │600 │ ├─────────────────────────┌──────┌──────┌──────┌──────┌─────┌───────── │Pays to the one to right │100.00│200.00│300.00│0.00 │ │600 │ └─────────────────────────┮──────┮──────┮──────┮──────┮─────┮────────┘ 

Note that the wraps - leftmost and rightmost tables are "neighbors".

We see that almost every guy makes a payment to his neighbor’s right column in the table and likewise receives one from his left neighbor. By adding what he initially paid, what he receives now, and what he pays now, he completes the correct total expense assigned to him.

However, if # 2 paid 100 and # 4 paid 300:

 ┌──────────┬───┬───┬───┬───┬─────┐ │Guy │1 │2 │3 │4 │Total│ ├──────────┌───┌───┌───┌───┌────── │Should pay│100│100│100│100│400 │ ├──────────┌───┌───┌───┌───┌────── │Payed │0 │100│0 │300│400 │ └──────────┮───┮───┮───┮───┮─────┘ 

we get 3 solutions, below the best:

 3 solutions with unique transfer sums. Best solution: ┌─────────────────────────┬──────┬──────┬──────┬────┬─────┬────────┐ │Guy # │1 │3 │4 │2 │Total│Turnover│ ├─────────────────────────┌──────┌──────┌──────┌────┌─────┌───────── │Should pay │100 │100 │100 │100 │400 │ │ ├─────────────────────────┌──────┌──────┌──────┌────┌─────┌───────── │Has paid │0 │0 │300 │100 │400 │ │ ├─────────────────────────┌──────┌──────┌──────┌────┌─────┌───────── │Gets from the one to left│0.00 │100.00│200.00│0.00│ │300 │ ├─────────────────────────┌──────┌──────┌──────┌────┌─────┌───────── │Pays to the one to right │100.00│200.00│0.00 │0.00│ │300 │ └─────────────────────────┮──────┮──────┮──────┮────┮─────┮────────┘ 

and worst:

 Worst solution: ┌─────────────────────────┬──────┬──────┬──────┬──────┬─────┬────────┐ │Guy # │1 │2 │4 │3 │Total│Turnover│ ├─────────────────────────┌──────┌──────┌──────┌──────┌─────┌───────── │Should pay │100 │100 │100 │100 │400 │ │ ├─────────────────────────┌──────┌──────┌──────┌──────┌─────┌───────── │Has paid │0 │100 │300 │0 │400 │ │ ├─────────────────────────┌──────┌──────┌──────┌──────┌─────┌───────── │Gets from the one to left│100.00│200.00│200.00│0.00 │ │500 │ ├─────────────────────────┌──────┌──────┌──────┌──────┌─────┌───────── │Pays to the one to right │200.00│200.00│0.00 │100.00│ │500 │ └─────────────────────────┮──────┮──────┮──────┮──────┮─────┮────────┘ 

The aforementioned is worse, because the total turnover in the settlement of payments is greater. You had this criterion:

I would like to minimize the excessive amount of money that a person receives in addition to what he or she actually owes.

In most cases this seems possible, but I doubt that there is any guarantee for this.

Now consider this situation:

 ┌──────────┬──┬──┬──┬──┬──┬──┬──┬──┬─────┐ │Guy │1 │2 │3 │4 │5 │6 │7 │8 │Total│ ├──────────┌──┌──┌──┌──┌──┌──┌──┌──┌────── │Should pay│10│10│10│10│10│10│10│10│80 │ ├──────────┌──┌──┌──┌──┌──┌──┌──┌──┌────── │Payed │0 │0 │0 │0 │0 │0 │0 │80│80 │ └──────────┮──┮──┮──┮──┮──┮──┮──┮──┮─────┘ 

The optimal (and only) solution:

 1 solutions with unique transfer sums. Best solution: ┌─────────────────────────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬────────┐ │Guy # │1 │2 │3 │4 │5 │6 │7 │8 │Total│Turnover│ ├─────────────────────────┌─────┌─────┌─────┌─────┌─────┌─────┌─────┌─────┌─────┌───────── │Should pay │10 │10 │10 │10 │10 │10 │10 │10 │80 │ │ ├─────────────────────────┌─────┌─────┌─────┌─────┌─────┌─────┌─────┌─────┌─────┌───────── │Has paid │0 │0 │0 │0 │0 │0 │0 │80 │80 │ │ ├─────────────────────────┌─────┌─────┌─────┌─────┌─────┌─────┌─────┌─────┌─────┌───────── │Gets from the one to left│0.00 │10.00│20.00│30.00│40.00│50.00│60.00│70.00│ │280 │ ├─────────────────────────┌─────┌─────┌─────┌─────┌─────┌─────┌─────┌─────┌─────┌───────── │Pays to the one to right │10.00│20.00│30.00│40.00│50.00│60.00│70.00│0.00 │ │280 │ └─────────────────────────┮─────┮─────┮─────┮─────┮─────┮─────┮─────┮─────┮─────┮────────┘ 

We see that the payment amount is increasing. Despite the fact that No. 7 has a debt of 10, he gets 60 and pays 70. The reason is that all the other guys should accumulate / increase the amount sufficient to pay up to # 8. As a criterion, that was No. 8 ( and every other person too) can receive money only from one other guy, and not from several.

Now consider a more complex task - each of them made their choice from the menu. Some paid for their own food, and # 8 took care of paying for # 1, No. 3, No. 5, No. 7 and themselves:

 ┌──────────┬──┬──┬──┬──┬──┬──┬──┬──┬─────┐ │Guy │1 │2 │3 │4 │5 │6 │7 │8 │Total│ ├──────────┌──┌──┌──┌──┌──┌──┌──┌──┌────── │Should pay│10│25│12│18│16│10│18│15│124 │ ├──────────┌──┌──┌──┌──┌──┌──┌──┌──┌────── │Payed │0 │25│0 │18│0 │10│0 │71│124 │ └──────────┮──┮──┮──┮──┮──┮──┮──┮──┮─────┘ 

The result is pretty good. Those who paid for themselves will not be touched:

 97 solutions with unique transfer sums. Best solution: ┌─────────────────────────┬─────┬─────┬─────┬─────┬─────┬────┬────┬────┬─────┬────────┐ │Guy # │1 │3 │5 │7 │8 │2 │4 │6 │Total│Turnover│ ├─────────────────────────┌─────┌─────┌─────┌─────┌─────┌────┌────┌────┌─────┌───────── │Should pay │10 │12 │16 │18 │15 │25 │18 │10 │124 │ │ ├─────────────────────────┌─────┌─────┌─────┌─────┌─────┌────┌────┌────┌─────┌───────── │Has paid │0 │0 │0 │0 │71 │25 │18 │10 │124 │ │ ├─────────────────────────┌─────┌─────┌─────┌─────┌─────┌────┌────┌────┌─────┌───────── │Gets from the one to left│0.00 │10.00│22.00│38.00│56.00│0.00│0.00│0.00│ │126 │ ├─────────────────────────┌─────┌─────┌─────┌─────┌─────┌────┌────┌────┌─────┌───────── │Pays to the one to right │10.00│22.00│38.00│56.00│0.00 │0.00│0.00│0.00│ │126 │ └─────────────────────────┮─────┮─────┮─────┮─────┮─────┮────┮────┮────┮─────┮────────┘ 

Then the case when, apparently, the good guys emptied all their pockets and received 124 dollars:

 ┌──────────┬──┬──┬──┬──┬──┬──┬──┬──┬─────┐ │Guy │1 │2 │3 │4 │5 │6 │7 │8 │Total│ ├──────────┌──┌──┌──┌──┌──┌──┌──┌──┌────── │Should pay│10│25│12│18│16│10│18│15│124 │ ├──────────┌──┌──┌──┌──┌──┌──┌──┌──┌────── │Payed │17│20│10│19│10│20│16│12│124 │ └──────────┮──┮──┮──┮──┮──┮──┮──┮──┮─────┘ 

Pretty good! No big money to move:

 67 solutions with unique transfer sums. Best solution: ┌─────────────────────────┬────┬────┬────┬────┬─────┬─────┬────┬────┬─────┬────────┐ │Guy # │1 │3 │4 │8 │5 │6 │7 │2 │Total│Turnover│ ├─────────────────────────┌────┌────┌────┌────┌─────┌─────┌────┌────┌─────┌───────── │Should pay │10 │12 │18 │15 │16 │10 │18 │25 │124 │ │ ├─────────────────────────┌────┌────┌────┌────┌─────┌─────┌────┌────┌─────┌───────── │Has paid │17 │10 │19 │12 │10 │20 │16 │20 │124 │ │ ├─────────────────────────┌────┌────┌────┌────┌─────┌─────┌────┌────┌─────┌───────── │Gets from the one to left│7.00│0.00│2.00│1.00│4.00 │10.00│0.00│2.00│ │26 │ ├─────────────────────────┌────┌────┌────┌────┌─────┌─────┌────┌────┌─────┌───────── │Pays to the one to right │0.00│2.00│1.00│4.00│10.00│0.00 │2.00│7.00│ │26 │ └─────────────────────────┮────┮────┮────┮────┮─────┮─────┮────┮────┮─────┮────────┘ 

And finally, the case when everything paid an equal amount, but obligations were differently resolved: must pay the same, but pay differently:

 ┌──────────┬──┬──┬──┬──┬──┬──┬──┬──┬─────┐ │Guy │1 │2 │3 │4 │5 │6 │7 │8 │Total│ ├──────────┌──┌──┌──┌──┌──┌──┌──┌──┌────── │Should pay│10│10│10│10│10│10│10│10│80 │ ├──────────┌──┌──┌──┌──┌──┌──┌──┌──┌────── │Payed │7 │20│10│5 │10│10│6 │12│80 │ └──────────┮──┮──┮──┮──┮──┮──┮──┮──┮─────┘ 

Tiny Turnover:

 54 solutions with unique transfer sums. Best solution: ┌─────────────────────────┬────┬────┬────┬─────┬─────┬────┬────┬────┬─────┬────────┐ │Guy # │1 │8 │7 │4 │2 │3 │5 │6 │Total│Turnover│ ├─────────────────────────┌────┌────┌────┌─────┌─────┌────┌────┌────┌─────┌───────── │Should pay │10 │10 │10 │10 │10 │10 │10 │10 │80 │ │ ├─────────────────────────┌────┌────┌────┌─────┌─────┌────┌────┌────┌─────┌───────── │Has paid │7 │12 │6 │5 │20 │10 │10 │10 │80 │ │ ├─────────────────────────┌────┌────┌────┌─────┌─────┌────┌────┌────┌─────┌───────── │Gets from the one to left│0.00│3.00│1.00│5.00 │10.00│0.00│0.00│0.00│ │19 │ ├─────────────────────────┌────┌────┌────┌─────┌─────┌────┌────┌────┌─────┌───────── │Pays to the one to right │3.00│1.00│5.00│10.00│0.00 │0.00│0.00│0.00│ │19 │ └─────────────────────────┮────┮────┮────┮─────┮─────┮────┮────┮────┮─────┮────────┘ 

How to make this calculation

As we do this with brute force, this means generating all permutations of the number of participants. This can be a tricky part. As an example, all the permutations (1,2,3,4) below (column by column, to increase readability):

 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4 2 2 3 3 4 4 1 1 3 3 4 4 1 1 2 2 4 4 1 1 2 2 3 3 3 4 2 4 2 3 3 4 1 4 1 3 2 4 1 4 1 2 2 3 1 3 1 2 4 3 4 2 3 2 4 3 4 1 3 1 4 2 4 1 2 1 3 2 3 1 2 1 

You are better off looking for this generation. This is normal if this happens in a loop. It is essential that you can access one column in time (or a row if they are different).

Pseudo:

 // NOTE: The data is written as arrays // For example "0 0 0 0" implies a 4-element array (vector) of integers // Of course there may be other number of participants ("guys"), // then we need "other-element" arrays, for example 7-element ones // The code below may require additional looping ToPay = 100 100 100 100 // Topmost example in this answer HasPayed = 0 0 0 400 // Ditto // Calculate debt // This probably requires a loop from 1...4 Debt[n] = ToPay[n] - HasPayed[n] // Debt is now: 100 100 100 -300 smallest = 9999999 // Sufficiently big initial value :For Row :In [each permutation of (1 2 3 4) // Row is now for example: 2 4 3 1 Test = Debt[Row] // Test is now for example: 100 -300 100 100 Accu = [4-element vector of zeroes] Accu[1] = Row[1] minimum = Row[1] s = 2 :Repeat Accu[s] = Accu[s-1] + Row[s] minimum = min(minimum, Accu[s]) // We simply grab the smalles element in Accu s += 1 :Until (s > 4) // As this is ready, Accu may contain eg. 100 -200 -100 0 // and minimum would then contain -200 sum = 0 t = 1 :Repeat Accu[t] -= minimum sum += Accu[t] t += 1 :Until (t > 4) // When ready, Accu would be eg. 300 0 100 200 // and sum would be 300+0+100+200, ie. 600 :If (sum < smallest) [store Row as best so far, for example into "BestRow"] [store Accu, for example into BestAccu"] smallest = sum :End :End 

Now

  • BestRow contains the order in which the guy pays another (from left to right), for example 1 2 3 4 (= 1 pays 2, 2 pays 3, 3 pays 4, 4 pays 1).
  • BestAccu contains the amount that the guy should pay to the right, for example 100,200,300.

You can apply other criteria for the "best way", but this solution minimizes the amount of "moved" money and saves transactions per payment per person.

It should also be noted that there are many “better solutions” where one permutation gives the same minimum turnover as another redistribution. In the last example, the number of equally good solutions was (the worst):

 48 96 144 144 240 240 480 336 672 432 768 912 960 768 1296 864 1392 1104 1200 1056 1488 1488 1488 1200 1344 1152 1776 1056 1344 1056 1152 1152 1344 768 1104 768 1056 720 912 480 672 528 528 240 576 288 432 192 288 144 240 48 96 48 

... means 48 "best solutions", 96 "second best", etc.


Edit:

I was told about a criterion that I mistakenly assumed: "A person can only receive money from one other person. This was not so, any person can give money only to one other person, but he does not have money , one person or several people.

It turns out that the above solution was almost complete. To solve this new condition, you only need to process the result a little. Namely, the accumulations that now exist in the aforementioned logic, where several people in a row can accumulate more and more money, while at the same time contributing to accumulation in order to pay off the one who made the big payment ("Mr. X"), is the accumulation must be dismantled, so that the cumulative part of it will be paid directly to X, and not through other participants.

Consider this situation:

 ┌──────────┬──┬──┬──┬──┬──┬──┬─────┐ │Guy │1 │2 │3 │4 │5 │6 │Total│ ├──────────┌──┌──┌──┌──┌──┌──┌────── │Should pay│10│10│20│30│10│20│100 │ ├──────────┌──┌──┌──┌──┌──┌──┌────── │Payed │35│0 │25│0 │0 │40│100 │ └──────────┮──┮──┮──┮──┮──┮──┮─────┘ 

Although it looks simple, it is rather difficult to solve by calculating the head, since it is circular. Using earlier methods, we get a "cumulative" answer:

 22 solutions with unique transfer sums. Best solution: ┌─────────────────────────┬──┬──┬──┬──┬──┬──┬─────┬────────┐ │Guy # │1 │3 │2 │5 │6 │4 │Total│Turnover│ ├─────────────────────────┌──┌──┌──┌──┌──┌──┌─────┌───────── │Should pay │10│20│10│10│20│30│100 │ │ ├─────────────────────────┌──┌──┌──┌──┌──┌──┌─────┌───────── │Has paid │35│25│0 │0 │40│0 │100 │ │ ├─────────────────────────┌──┌──┌──┌──┌──┌──┌─────┌───────── │Gets from the one to left│30│5 │0 │10│20│0 │ │65 │ ├─────────────────────────┌──┌──┌──┌──┌──┌──┌─────┌───────── │Pays to the one to right │5 │0 │10│20│0 │30│ │65 │ └─────────────────────────┮──┮──┮──┮──┮──┮──┮─────┮────────┘ 

Then we can resolve the debt for each of them, this is the second row - the third row (positive debt):

 ┌───┬──┬──┬──┬───┬──┐ │-25│-5│10│10│-20│30│ └───┮──┮──┮──┮───┮──┘ 

Using this, we can solve something called "accumulation" that the 5th line is a debt:

 ┌──┬─┬─┬──┬──┬─┐ │30│5│0│10│20│0│ └──┮─┮─┮──┮──┮─┘ 

From this, we can decide which payments can be changed from “pay the guy to the right” for the “paid guy #n” - this simply happens by comparing the pairs from the accumulation and comparing the last element of the accumulation with the first (since this problem is circular). (30 < 5), (5 < 0), (0 < 10) ..; (0 < 30):

 ┌─┬─┬─┬─┬─┬─┐ │0│0│1│1│0│1│ └─┮─┮─┮─┮─┮─┘ 

1 , - , #n.

#n? #n . 3 4 ( № 2 № 5 ) №6 - , №2 №5, .

, , . , , ( ) , . :

 ┌──────────┬──┬──┬──┬──┬──┬──┐ │Guy │1 │3 │2 │5 │6 │4 │ ├──────────┌──┌──┌──┌──┌──┌─── │Should pay│10│20│10│10│20│30│ ├──────────┌──┌──┌──┌──┌──┌─── │Payed │35│25│0 │0 │40│0 │ ├──────────┌──┌──┌──┌──┌──┌─── │Pays to │3 │ │6 │6 │ │1 │ ├──────────┌──┌──┌──┌──┌──┌─── │Amount │5 │ │10│10│ │30│ └──────────┮──┮──┮──┮──┮──┮──┘ 

, №1, "", 5 №3. , № 4 ( ) 30, - "" # 1, # 1 №3 5 -, 1 . , # 6 20 # 2 №5. , ?: -)

( ). 2 :

  ┌──────────┬──┬──┬──┬─┬─┬──┬──┬──┬─────┐ ┌───────┬─┬─┬──┬──┬─┬─┬──┬──┐ │Guy │1 │2 │3 │4│5│6 │7 │8 │Total│ │Guy │1│5│6 │8 │2│4│7 │3 │ ├──────────┌──┌──┌──┌─┌─┌──┌──┌──┌────── ├───────┌─┌─┌──┌──┌─┌─┌──┌─── │Should pay│7 │11│13│8│5│10│12│14│80 │ │Pays to│ │2│2 │2 │ │1│1 │1 │ ├──────────┌──┌──┌──┌─┌─┌──┌──┌──┌────── ├───────┌─┌─┌──┌──┌─┌─┌──┌─── │Payed │40│40│0 │0│0│0 │0 │0 │80 │ │Amount │ │5│10│14│ │8│12│13│ └──────────┮──┮──┮──┮─┮─┮──┮──┮──┮─────┘ └───────┮─┮─┮──┮──┮─┮─┮──┮──┘ 

:

  ┌──────────┬──┬───┬──┬──┬──┬──┬──┬──┬──┬──┬─────┐ ┌───────┬─┬──┬──┬──┬──┬──┬──┬─┬──┬─┐ │Guy │1 │2 │3 │4 │5 │6 │7 │8 │9 │10│Total│ │Guy │1│3 │7 │4 │10│6 │8 │2│5 │9│ ├──────────┌──┌───┌──┌──┌──┌──┌──┌──┌──┌──┌────── ├───────┌─┌──┌──┌──┌──┌──┌──┌─┌──┌── │Should pay│10│10 │10│12│10│19│11│33│6 │12│133 │ │Pays to│2│2 │2 │2 │2 │2 │2 │ │9 │1│ ├──────────┌──┌───┌──┌──┌──┌──┌──┌──┌──┌──┌────── ├───────┌─┌──┌──┌──┌──┌──┌──┌─┌──┌── │Payed │5 │112│0 │0 │0 │1 │0 │0 │15│0 │133 │ │Amount │6│10│11│12│12│18│33│ │10│1│ └──────────┮──┮───┮──┮──┮──┮──┮──┮──┮──┮──┮─────┘ └───────┮─┮──┮──┮──┮──┮──┮──┮─┮──┮─┘ 

:

  ┌──────────┬──┬──┬──┬──┬──┬──┬──┬──┬─┬──┬─────┐ ┌───────┬──┬──┬─┬─┬─┬─┬─┬──┬──┬─┐ │Guy │1 │2 │3 │4 │5 │6 │7 │8 │9│10│Total│ │Guy │1 │10│4│9│5│3│6│7 │8 │2│ ├──────────┌──┌──┌──┌──┌──┌──┌──┌──┌─┌──┌────── ├───────┌──┌──┌─┌─┌─┌─┌─┌──┌──┌── │Should pay│10│10│5 │12│10│19│11│33│6│12│128 │ │Pays to│10│ │9│5│3│ │2│2 │2 │ │ ├──────────┌──┌──┌──┌──┌──┌──┌──┌──┌─┌──┌────── ├───────┌──┌──┌─┌─┌─┌─┌─┌──┌──┌── │Payed │7 │50│10│10│6 │12│1 │10│7│15│128 │ │Amount │3 │ │2│1│5│ │7│10│23│ │ └──────────┮──┮──┮──┮──┮──┮──┮──┮──┮─┮──┮─────┘ └───────┮──┮──┮─┮─┮─┮─┮─┮──┮──┮─┘ 

, .

+2
source

All Articles