Expense Sharing System
Integer accounting and idempotent operations
Ownership and transitions
Integer cents make conservation exact. Split quotient plus remainder in sorted participant order rather than rounding fractions. Net balances remain zero-sum after an expense and after settlement. Canonicalize participant membership before storing an idempotency fingerprint; exact retries must be checked before balance-dependent settlement checks. Suggestions work on copies and claim deterministic pairing, not a minimum transfer count.
Java boundaries
Use the supplied nested records as immutable value carriers. A record is only shallowly immutable: copy every retained mutable input and every outward list/map, including lists inside records. Absence is null; validation failures use IllegalArgumentException, missing-key purchase errors use NoSuchElementException, and invalid transaction boundaries use IllegalStateException. Java primitive types already exclude booleans from numeric inputs. Numeric values use long where signatures say long and all computations must fit signed 64-bit values. Calls in these service exercises are serialized.
Remainder cents are assigned deterministically rather than rounded. The integer quotient and remainder together preserve the total:
import java.util.*;
class Example {
public static void main(String[] args) {
long total = 5, count = 3;
long base = total / count, remainder = total % count;
assert base == 1 && remainder == 2;
assert 2 + 2 + 1 == total;
assert 2 - 1 - 1 == 0; // each net transition remains zero-sum
}
}The first two sorted participants receive the extra cent. Canonical participant membership also makes a reordered exact retry equivalent, without applying the expense twice.
Design boundary
Expenses and settlements share one operation-ID namespace. Recognize exact settlement replay before balance-dependent checks because the first accepted payment changed those balances. Suggestions operate on copies and promise deterministic pairing, not a globally minimal number of transfers.
Put it into practice
Implement the exercise in a full-screen workspace, then run its tests.