Match payments to invoices by memo or amount
GoogleData Scientist · Technical ScreenLast updated
This problem tests string parsing, hash-map based data indexing, and multi-criteria reconciliation logic (fuzzy matching via IDs vs. exact matching via amount).
Problem Statement
You are provided with two lists: a list of invoices and a list of payments. Each invoice has an id and an amount. Each payment has an amount, a memo string, and a date.
Your task is to reconcile these lists according to the following precedence rules:
- ID Match: If an invoice
idis found anywhere inside a payment'smemo(as a substring), match them. If multiple invoices match a single payment memo, prioritize the one with the highest amount. - Amount Match: If no invoice ID is found in the memo, match the payment to an unpaid invoice with the exact same
amount. - Tie-breaking: If multiple invoices have the same amount, match the payment to the invoice with the earliest date.
Function Signature
def reconcile_payments(invoices, payments):
# invoices: List of dicts {'id': str, 'amount': float, 'date': str}
# payments: List of dicts {'amount': float, 'memo': str, 'date': str}
# Return a list of tuples: (payment_index, matched_invoice_id)
pass
Example
Input:
invoices = [{'id': 'INV-001', 'amount': 100.0, 'date': '2023-01-01'}, {'id': 'INV-002', 'amount': 200.0, 'date': '2023-01-02'}]
payments = [{'amount': 100.0, 'memo': 'Paid INV-001'}, {'amount': 200.0, 'memo': 'Final balance'}]
Output:
[(0, 'INV-001'), (1, 'INV-002')]
Constraints
- Number of invoices and payments: up to 10,000 each.
- Invoice IDs are unique.
- Each payment can be matched to at most one invoice.
Hints
Hint 1
Use a hash map to group invoices by their amount for O(1) lookups during the amount-matching phase.
Hint 2
For the ID-based matching, consider pre-processing the invoice IDs into a set or using a regex-friendly structure if IDs are complex.
Hint 3
Maintain a set of matched invoice IDs to ensure each invoice is only reconciled once.
Follow-up questions
- How would you optimize the solution if the invoice list was so large it could not fit into memory?
- What changes are required if the payment amount is allowed to match a total of multiple invoices (e.g., one payment covers two smaller invoices)?
- How would you handle 'near-match' amounts (e.g., payments within 1% of the invoice amount)?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.