Sign in to run and submit your work
Reading is open to everyone. Running code and saving drafts need an account so your work is yours and comes back on your next visit.
or
CODE WORKSPACE
Finance reconciliation has a refund that a customer says covers exactly two of their card payments, but the refund record does not say which. The payments arrive as a settlement feed in the order they settled, and the team needs the pair automatically so the refund can be linked to them in the ledger.
Write find_payment_pair(payments, refund_cents). It takes payments, a list of dicts like {"id": "p1", "amount_cents": 500} in settlement order, and refund_cents, an integer, and returns [id_a, id_b] — the ids of the two payments whose amounts sum exactly to the refund, with id_a the one that settled first.
Function to write
find_payment_pair(payments: list[dict], refund_cents: int) -> list[str]The ids [id_a, id_b] of the first pair of distinct payments that sums to the refund, or [].
How to approach it
For each payment the partner amount is fixed: refund minus this amount. Ask a dict of amounts you have already seen, and record the current payment only after asking.
Sample cases
+ 2 held back until you submit
two pairs could settle the refund
p2+p3 and p1+p4 both make 1250; p3 settles before p4, so [p2, p3] is the pair a scan completes first.
Input
Argument 1
| id | amount_cents |
|---|---|
| p1 | 500 |
| p2 | 300 |
| p3 | 950 |
| p4 | 750 |
Argument 2
1250Returns
[
'p2',
'p3'
]one payment cannot be used twice
500 + 500 is 1000, but there is only one 500 payment — the real pair is 700 and 300.
Input
Argument 1
| id | amount_cents |
|---|---|
| a1 | 500 |
| a2 | 250 |
| a3 | 700 |
| a4 | 300 |
Argument 2
1000Returns
[
'a3',
'a4'
]nothing adds up to the refund
No two payments sum to the refund, so the answer is an empty list rather than None.
Input
Argument 1
| id | amount_cents |
|---|---|
| x1 | 100 |
| x2 | 200 |
Argument 2
1000Returns
[] (empty list)
no payments settled
An empty day of payments returns an empty list without raising.
Input
Argument 1
[] (empty list)
Argument 2
500Returns
[] (empty list)
Constraints
[id_a, id_b], where id_a settled before id_b (appears earlier in the list).[], never None. An empty payments list returns [].Worked example
Take the refund of 1250 against p1 500, p2 300, p3 950, p4 750. Walk left to right, and for each payment ask the dict whether the amount that completes it has already settled. At p1 the partner would be 750: not seen, so record 500 → p1. At p2 the partner is 950: not seen, record 300 → p2. At p3 the partner is 1250 − 950 = 300, and the dict has it: return ["p2", "p3"]. The scan never reaches p4, even though p1 + p4 is also 1250.
The trap is in the second visible case: a refund of 1000 with a single 500 payment. If you record 500 → a1 before looking up its partner, a1 finds itself and you return ["a1", "a1"] instead of the real pair, 700 and 300.
What this tests
The hash lookup pattern: this is LeetCode 'Two Sum' in data clothing. The target is O(n) time and O(n) space — the nested-loop O(n²) version passes these samples and times out on a day of a million settlements. A data engineer meets it for real in reconciliation: matching refunds, chargebacks or transfers to the transactions that explain them. It is reported in data engineering loops: 'Two Sum' is tagged for data engineers at Amazon, Google, Apple, Visa, PayPal and Goldman Sachs on Exponent.
find_payment_pair(payments: list[dict], refund_cents: int) -> list[str]Submit for review to find out what your query gets right, what it gets wrong, and how it compares with the best working query for this exercise.
This scenario runs a full workspace — editor, canvas and results side by side. It needs a laptop or desktop to be usable. Open this page on a bigger screen to start building.