Fraud Ring Size
Reported by candidates from Stripe's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Stripe's July 2026 OA has a fraud ring problem that looks like a log-parsing chore and is really a connected components question. It's Task 2 of 3, so you've likely just seen the direct-links version and the next one builds on this. You get transactions as user,device,card strings and a target user. Count everyone reachable through shared devices or cards. If you're taking it in a day or two, learn the union-find or graph traversal shape now. StealthCoder sits invisibly as a safety net if your mind goes blank mid-assessment.
The problem
Stripe Fraud Ring Tasks
This problem is Task 2 of 3 in the Stripe fraud-ring sequence.
Task 1: Directly Linked Users
Task 2: Fraud Ring Size (current)
Task 3: Risky Fraud Ring
Direct links alone are insufficient for detecting sophisticated fraud rings, as bad actors may rotate devices to avoid simple detection logic. However, they often still share financial instruments.
A Fraud Ring is the full set of users connected by any chain of shared identifiers. If User A shares a device with User B, and User B shares a credit card with User C, then User A and User C are part of the same coordinated ring.
The goal is to quantify the size of the threat. Each transaction includes a user ID, a device ID, and a credit-card hash. Given a target user, calculate the total number of unique users within that user's extended Fraud Ring.
Input
transactions: a list of strings, where each string is formatted as user_id,device_id,credit_card.
targetUser: the user ID to investigate.
Note: A single user may appear multiple times in the transaction log with different identifiers. For example, if Alice uses Device A and Device B, she links those two devices together. Anyone on Device A is therefore connected to anyone on Device B through Alice.
Output
Return the number of unique users in the Fraud Ring containing targetUser, including targetUser.
Function
getFraudRingSize(transactions: String[], targetUser: String) → int
Examples
Example 1
transactions = ["Alice,D1,CC1","Bob,D1,CC2","Charlie,D2,CC2","David,D3,CC3","Eve,D3,CC4"]
targetUser = "Alice"
return = 3
Alice used Device D1. Bob also used Device D1, linking Alice and Bob.
Bob used Credit Card CC2. Charlie also used Credit Card CC2, linking Bob and Charlie.
David is on Device D3 and Card CC3, sharing no overlap with the Alice, Bob, Charlie cluster. Eve is on Device D3, linking Eve to David, but they remain disjoint from Alice.
The extended ring containing Alice consists of {Alice, Bob, Charlie}, resulting in a size of 3.
Example 2
transactions = ["A,D1,C1","B,D2,C2","C,D3,C3"]
targetUser = "A"
return = 1
No other user shares an identifier with A, so its Fraud Ring contains only A.
Constraints
1 <= transactions.length <= 10^5.
Every transaction contains exactly three non-empty, comma-free fields: user_id, device_id, and credit_card.
targetUser appears in at least one transaction.
A user may appear in multiple transactions, and every occurrence represents the same user.Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick: users, devices, and cards are all nodes, and each transaction joins its three identifiers. Run union-find over strings, prefixing them (u:, d:, c:) so a user named D1 can't collide with a device D1. Union the user with the device and the user with the card on every row. Then find the target's root and count distinct users whose root matches. The pitfall is counting all nodes in the component instead of only users. Another is building user-to-user edges pairwise, which blows up to O(n^2) when many users share one device. Linking through identifier nodes keeps it near O(n). BFS on a bipartite-style graph works too, but watch recursion depth at 10^5 rows if you use DFS. StealthCoder is your hedge if the union-find code escapes you live.
If this hits your live OA and you blank, StealthCoder solves it in seconds, invisible to the proctor.
You can drill Fraud Ring Size 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. Built by an Amazon engineer who would have shipped this the night before his JPMorgan OA if he'd had it.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Stripe's OA.
Stripe reuses patterns across OAs. Built by an Amazon engineer who would have shipped this the night before his JPMorgan OA if he'd had it. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Fraud Ring Size FAQ
What's the trick in Fraud Ring Size?+
Treat devices and cards as nodes alongside users. Union each transaction's user with its device and its card. Everyone in the target's component is in the ring. Then count only the user nodes, not devices or cards, or your answer will be inflated.
Should I use union-find or BFS?+
Either works for 10^5 rows. Union-find with path compression is short and avoids recursion limits. BFS over an adjacency map is fine too if you use an iterative queue. Pick whichever you can write without bugs under pressure.
Why prefix the identifiers?+
User IDs, device IDs, and card hashes are all plain strings in one namespace if you're careless. A user called D1 would merge with device D1 and give a wrong count. Prefixing with u:, d:, c: or using three separate maps prevents that.
What are the edge cases to test?+
Test a target who appears in only one transaction with no overlaps, which should return 1. Test a chain linking through a device then a card, as in Example 1. Test one user appearing in many rows, which merges their devices and cards together.
How do I prepare in 48 hours for this Stripe OA?+
Write union-find from memory twice, with find, union, and path compression. Then solve a connected-components problem over strings. Since this is Task 2 of 3, expect Task 3 to add a condition on the ring, so keep your component structure easy to extend.