Reported November 2024
Stripehash table

Brazilian Receivables Part 3 — Partial Contracts

Reported by candidates from Stripe's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.

Get StealthCoderRuns invisibly during the live Stripe OA. Under 2s to a working solution.
Founder's read

Stripe reported this one in November 2024, and the constraint is what shapes the answer: up to 100000 rows in each CSV, so any approach that rescans transactions for every contract will crawl. This is Part 3 of the Brazilian Receivables series, a parse, aggregate, subtract, sort job. If your OA invite is sitting in your inbox, expect string handling and hash maps, not clever algorithms. The work is in the details of the output format. StealthCoder is the invisible safety net on your screen if you blank on the CSV plumbing mid-assessment, but the plan below should keep you out of trouble.

The problem

Brazilian card transactions are registered as daily receivables. You are given two valid CSV strings.
transactionsCsv has header customer_id,merchant_id,payout_date,card_type,amount.
contractsCsv has header contract_id,merchant_id,payout_date,card_type,amount.
Aggregate transactions by (merchant_id, card_type, payout_date). Each contract buys only its stated amount from the matching merchant receivable. Create a contract-ID receivable for that amount and subtract it from the merchant receivable. Keep the merchant row when its remaining amount is positive; remove it when the remaining amount is zero.
Return CSV rows beginning with id,card_type,payout_date,amount. Sort the data rows by Unicode code points in ID, then card type, then payout date. When all three strings are equal, sort by amount numerically in ascending order. Write each output amount in base-10 notation without leading zeros.

Function
allocatePartialContracts(transactionsCsv: String, contractsCsv: String) → String[]

Examples
Example 1
transactionsCsv = "customer_id,merchant_id,payout_date,card_type,amount\ncust1,merchantA,2022-01-07,Visa,500"
contractsCsv = "contract_id,merchant_id,payout_date,card_type,amount\ncontract1,merchantA,2022-01-07,Visa,200"
return = ["id,card_type,payout_date,amount","contract1,Visa,2022-01-07,200","merchantA,Visa,2022-01-07,300"]
The contract buys 200 of the 500 receivable, leaving 300 under the merchant ID.
Example 2
transactionsCsv = "customer_id,merchant_id,payout_date,card_type,amount\nc1,m1,2024-01-01,Visa,300\nc2,m1,2024-01-01,Visa,250\nc3,m2,2024-01-02,MasterCard,700"
contractsCsv = "contract_id,merchant_id,payout_date,card_type,amount\nk1,m1,2024-01-01,Visa,550"
return = ["id,card_type,payout_date,amount","k1,Visa,2024-01-01,550","m2,MasterCard,2024-01-02,700"]
A full-amount contract removes the matching merchant receivable. The unrelated merchant remains.
Example 3
transactionsCsv = "customer_id,merchant_id,payout_date,card_type,amount\nc1,zeta,2024-02-01,Visa,100\nc2,alpha,2024-02-02,Amex,80"
contractsCsv = "contract_id,merchant_id,payout_date,card_type,amount"
return = ["id,card_type,payout_date,amount","alpha,Amex,2024-02-02,80","zeta,Visa,2024-02-01,100"]
With no contracts, both aggregates remain and are sorted by output ID.

Constraints
Each CSV contains its exact header followed by between 0 and 100000 data rows.
Fields contain no commas, line breaks, or surrounding whitespace.
Amounts are positive integers at most 10^9; every aggregate fits a signed 64-bit integer.
Each contract maps to exactly one aggregated merchant receivable, its amount does not exceed that receivable, and no two contracts map to the same receivable.

Reported by candidates. Source: FastPrep

Pattern and pitfall

The trick is a hash map keyed on (merchant_id, card_type, payout_date) that sums amounts in one pass over transactions. Then walk the contracts once. Each contract looks up its key in O(1), emits a row under the contract ID for its amount, and subtracts that amount from the merchant total. Because every contract maps to exactly one receivable and no two share one, there's no splitting logic to worry about. After that, emit merchant rows only where the remainder is positive. The pitfalls are all in the edges. Sort by plain code point comparison, not locale-aware compare. Tie-break on amount numerically, not as a string. Handle a contracts CSV that has only a header. Use 64-bit sums. Always output the header row first. If you freeze on any of this live, StealthCoder can hand you the working skeleton while you check the details.

Memorize the pattern. If you can't, run StealthCoder. The proctor sees the IDE. They don't see what's behind it.

If this hits your live OA

You can drill Brazilian Receivables Part 3 — Partial Contracts cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Made by an engineer who treats the OA as theater. If yours is tonight, you don't have time to grind. You have time to hedge.

Get StealthCoder

Related leaked OAs

⏵ The honest play

You've seen the question. Make sure you actually pass Stripe's OA.

Stripe reuses patterns across OAs. Made by an engineer who treats the OA as theater. If yours is tonight, you don't have time to grind. You have time to hedge. Works on HackerRank, CodeSignal, CoderPad, and Karat.

Brazilian Receivables Part 3 — Partial Contracts FAQ

How hard is the Stripe Brazilian Receivables Part 3 problem really?+

Medium at most. No advanced algorithm is involved. It's CSV parsing, a hash map aggregation, a subtraction pass, and a custom sort. Most failures come from output formatting and sort rules, not from the core logic.

What's the main trick to avoid a timeout?+

Aggregate transactions into a map keyed by merchant, card type and payout date in one pass. Then each contract is a single lookup. With 100000 rows per CSV, nested loops over transactions and contracts will be too slow.

How should I sort the output rows?+

Compare ID, then card type, then payout date by Unicode code points, which is plain string comparison in most languages. If all three match, compare amount as a number ascending. Don't compare amounts as strings, since 100 would sort before 20.

What edge cases should I test before submitting?+

Test an empty contracts CSV with only a header, a contract that consumes the full receivable so the merchant row disappears, and multiple transactions merging into one key. Also check large sums near 10^9 times many rows so you use 64-bit math.

How do I prepare for this in 48 hours?+

Write a small parser that splits lines and commas, then practice grouping with a map and sorting with a custom comparator. Run the three given examples by hand. That covers nearly everything this problem tests.

Problem reported by candidates from a real Online Assessment. Sourced from a publicly-available candidate-aggregated repository. Not affiliated with Stripe.

OA at Stripe?
Invisible during screen share
Get it