Design an Expense Sharing Application
Build an in-memory expense sharing application that allows users to split expenses using equal, exact, and percentage-based splits while maintaining balances between users.
Expense-sharing applications allow groups of people to track shared expenses and automatically calculate who owes money to whom.
Imagine you live with three friends:
You: User1 (u1)
Flatmate: User2 (u2)
Flatmate: User3 (u3)
Flatmate: User4 (u4)
Throughout the month, different people pay for electricity, shopping, dinner, groceries, and other shared expenses.
The application should allow users to add these expenses, split them among multiple people, and maintain the balances between users.
This one tests whether you can model split strategies cleanly — equal, exact, and percentage with validation and rounding — while maintaining a correctly netted balance ledger so opposite debts never coexist.
Objective
The primary objective is to design and implement an in-memory expense sharing application where users create expenses, split them via pluggable strategies, and query netted balances per user or for the whole group, with extensibility for share-based splits, passbooks, and balance simplification.
Functional Requirements
Requirements are split into three tiers so you know what to prioritize under time pressure: build first, build if time allows, and validate strictly.
Part 1 — Basic Requirements
Core functionality you must build and get working first.
1. User
You can create a few users directly in the main method. There is no need to take user creation as input.
2. Expense
For example, User1 pays a ₹1000 electricity bill for all four flatmates and chooses to split it equally:
EXPENSE u1 4 u1 u2 u3 u4 EQUAL
Each person's share is ₹250. Since User1 already paid the entire amount:
u2 owes u1: 250.00
u3 owes u1: 250.00
u4 owes u1: 250.00
Later, User1 buys items for User2 and User3:
EXPENSE u1 2 u2 u3 EXACT 370 880
Now the balances become:
u2 owes u1: 620.00
u3 owes u1: 1130.00
u4 owes u1: 250.00
The application should continuously update these balances as new expenses are added.
3. Balance Management
Accumulation example — starting from u2 owes u1: 250.00, after another ₹370:
u2 owes u1: 620.00
Netting example:
u1 owes u4: 480.00
u4 owes u1: 250.00
→ netted to: u1 owes u4: 230.00
4. Show Balances
For example:
SHOW u1
could output:
u1 owes u4: 230.00
u2 owes u1: 620.00
u3 owes u1: 1130.00
If there are no balances:
No balances
Part 2 — Bonus Features
Extensibility checks — can your design add names, metadata, share-based splits, history, and simplification without touching the core balance engine.
SHARE Split
For example, User4 pays ₹1200 and the expense is split using shares:
EXPENSE u4 4 u1 u2 u3 u4 SHARE 2 1 1 1
The total shares are 2 + 1 + 1 + 1 = 5, therefore:
u1: 2/5 × 1200 = ₹480
u2: 1/5 × 1200 = ₹240
u3: 1/5 × 1200 = ₹240
u4: 1/5 × 1200 = ₹240
Passbook
The application can optionally maintain a transaction history for each user.
PASSBOOK u2
could display:
Electricity Bill
Paid by: u1
Your share: ₹250.00
Flipkart Shopping
Paid by: u1
Your share: ₹370.00
Dinner
Paid by: u4
Your share: ₹240.00
The exact output format is up to you.
Simplify Expenses
The application can optionally simplify the overall balances to minimize the number of cash-flow transactions.
For example, suppose 3 outstanding debts:
u1 owes u2: 120.00
u2 owes u3: 80.00
u1 owes u3: 50.00 // 3 transactions
After simplification, this collapses to 2 transactions:
u1 owes u3: 130.00
u1 owes u2: 40.00 // 2 transactions — same nets, one fewer hop
Each intermediate hop (u1→u2→u3) is cancelled by netting — the algorithm is O(n log n) with two heaps (debtors/creditors) and guarantees ≤ n−1 transactions instead of O(n²).
Part 3 — Validations & Rules
Discuss-only mechanics that must hold even in the basic implementation.
1. Equal Split
For an EQUAL expense, divide the total amount equally among all participants.
User1 pays ₹1000 for four people:
EXPENSE u1 4 u1 u2 u3 u4 EQUAL
Each person's share is 250.00 — resulting in u2/u3/u4 owe u1: 250.00 each.
2. Exact Split
For an EXACT expense, the exact amount owed by every participant is provided.
EXPENSE u1 2 u2 u3 EXACT 370 880
Total is 370 + 880 = 1250, giving u2 owes u1: 370.00 and u3 owes u1: 880.00.
For an EXACT split, the sum of all provided amounts must be equal to the total expense amount. If the values do not add up, the expense should be rejected.
3. Percentage Split
For a PERCENT expense, the percentage share of every participant is provided.
EXPENSE u4 4 u1 u2 u3 u4 PERCENT 40 20 20 20
If User4 pays ₹1200: u1: 40% = ₹480, u2/u3/u4: 20% = ₹240 each — so u1 owes u4: 480.00 etc.
For a PERCENT split, the sum of all percentages must be exactly 100%. If not, the expense should be rejected.
4. Decimal Values
The percentage and exact amount values can contain decimals up to two decimal places — e.g., 33.33, 33.34, 12.50.
5. Rounding
Example — ₹100 split equally among three people (100 / 3 = 33.333...):
33.34 + 33.33 + 33.33 = 100.00
6. Balance Calculation
Whenever an expense is added, update the balances between the payer and the participants. The payer's own share should not create a self-balance.
7. Netting Opposite Balances
If two users owe each other, net them to a single direction. There should never be two opposite non-zero balances between the same pair.
8. Input Format
Examples:
EXPENSE u1 4 u1 u2 u3 u4 EQUAL
EXPENSE u1 2 u2 u3 EXACT 370 880
EXPENSE u4 4 u1 u2 u3 u4 PERCENT 40 20 20 20
SHOW
SHOW u1
9. Output Format
When showing balances, use:
<user-id-of-x> owes <user-id-of-y>: <amount>
u2 owes u1: 620.00
u3 owes u1: 1130.00
u1 owes u4: 230.00
If the user owes money, they appear on the left; if owed, on the right. If no balances: No balances.
Example Usage: Full Walkthrough
1. Create Users
Create four users in the main method:
u1 - User1
u2 - User2
u3 - User3
u4 - User4
2. Electricity Bill
This month's electricity bill is ₹1000. User1 pays and splits equally among all four.
> EXPENSE u1 4 u1 u2 u3 u4 EQUAL
The application calculates:
u1: ₹250.00
u2: ₹250.00
u3: ₹250.00
u4: ₹250.00
Balances:
u2 owes u1: 250.00
u3 owes u1: 250.00
u4 owes u1: 250.00
3. Flipkart Shopping
User1 buys items for User2 and User3. Total ₹1250 with different shares.
> EXPENSE u1 2 u2 u3 EXACT 370 880
Balances now:
u2 owes u1: 620.00
u3 owes u1: 1130.00
u4 owes u1: 250.00
4. Dinner With Flatmates
User4 pays ₹1200. User1's share is 40%.
> EXPENSE u4 4 u1 u2 u3 u4 PERCENT 40 20 20 20
Shares:
u1: ₹480.00
u2: ₹240.00
u3: ₹240.00
u4: ₹240.00
Updated balances:
u1 owes u4: 230.00
u2 owes u1: 620.00
u2 owes u4: 240.00
u3 owes u1: 1130.00
u3 owes u4: 240.00
Notice User1 previously had u4 owes u1: 250.00 and now owes 480.00 — netted to 480 - 250 = 230 → u1 owes u4: 230.00.
5. Show All Balances
> SHOW
Possible output:
u1 owes u4: 230.00
u2 owes u1: 620.00
u2 owes u4: 240.00
u3 owes u1: 1130.00
u3 owes u4: 240.00
Only non-zero balances are displayed.
6. Show Balance for User1
> SHOW u1
Output:
u1 owes u4: 230.00
u2 owes u1: 620.00
u3 owes u1: 1130.00
7. User With No Balance
> SHOW u5
Output:
No balances
The final application allows users to add expenses using equal, exact, and percentage splits, correctly validates and rounds the shares, maintains net balances between users, and displays balances for either the entire group or an individual user.