Reported July 2026
Stripeunion find

Risky Fraud Ring

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 July 2026, and it's Task 3 of a three-part fraud-ring sequence. The whole thing hinges on union-find (disjoint set union), or a graph traversal if you'd rather build adjacency lists. You parse transaction rows, link users who share a device or a credit card, then check whether the target's ring averages strictly above 75. Trusted users with score 0 connect the graph but don't count. If your head goes blank on the setup, StealthCoder runs invisibly on the live OA as a safety net, but the logic here is short enough to hold in your head tonight.

The problem

Stripe Fraud Ring Tasks
This problem is Task 3 of 3 in the Stripe fraud-ring sequence.
Task 1: Directly Linked Users
Task 2: Fraud Ring Size
Task 3: Risky Fraud Ring (current)
Not every connected cluster is malicious. Each transaction includes a risk score, and a fraud ring should be blocked only when its average risk is high.
Each transaction log entry is formatted as user_id,device_id,credit_card,risk_score. Users are connected by shared devices or credit cards. The ring for a target user is the connected component containing that user.
A user with risk score 0 is trusted. Trusted users still keep the graph connected, but they are excluded from both the sum and count when computing the average risk score.
Return true if the average risk score of non-trusted users in the target ring is strictly greater than 75; otherwise return false.
Input
transactions: transaction rows formatted as user_id,device_id,credit_card,risk_score.
targetUser: the user to investigate.
Output
Return whether the target ring should be blocked.

Function
shouldBlockFraudRing(transactions: String[], targetUser: String) → boolean

Examples
Example 1
transactions = ["Alice,D1,CC1,90","Bob,D1,CC2,0","Charlie,D2,CC2,80"]
targetUser = "Alice"
return = true
The connected ring is Alice, Bob, and Charlie. Bob has score 0, so the average is (90 + 80) / 2 = 85, which is greater than 75.
Example 2
transactions = ["Alice,D1,CC1,70","Bob,D1,CC2,0","Charlie,D2,CC2,80"]
targetUser = "Alice"
return = false
Bob still connects Alice and Charlie, but Bob is excluded from the average. (70 + 80) / 2 = 75, and the rule requires strictly greater than 75.

Constraints
0 <= transactions.length <= 10^5
0 <= risk_score <= 100
Each user has the same risk score across all their transactions.

Reported by candidates. Source: FastPrep

Pattern and pitfall

Use union-find over user IDs. For each row, union the user with a key for the device and a key for the card, like "D:" + device and "C:" + card, so shared resources merge users automatically. Store each user's score once, since it's the same across rows. Then find the target's root, loop over every user in that root's component, and skip anyone with score 0. Sum the rest and count them. Compare sum > 75 * count, using integers, so you dodge float issues and the strictly-greater edge case from Example 2. The pitfalls are real. Don't drop score-0 users from the graph, because Bob must still bridge Alice and Charlie. Handle a ring where everyone is trusted, since count is 0 and you should return false. If the OA stalls you, StealthCoder is the hedge, reading the problem and giving a working solution live.

The honest play: practice the pattern, and have StealthCoder ready for the one you didn't see coming.

If this hits your live OA

You can drill Risky Fraud Ring 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 for the candidate who saw this exact problem leak two days before his OA and wondered if anyone had a play.

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. Built for the candidate who saw this exact problem leak two days before his OA and wondered if anyone had a play. Works on HackerRank, CodeSignal, CoderPad, and Karat.

Risky Fraud Ring FAQ

What's the trick in Risky Fraud Ring?+

Build connectivity first, filter second. Union users through shared device and card keys, including score-0 users, because they act as bridges. Only when computing the average do you exclude them. Mixing those two steps up is the most common way to fail the examples.

Should I use union-find or DFS?+

Either works for up to 10^5 rows. Union-find is shorter: map users, devices, and cards to nodes, union per row, then group by root. DFS needs adjacency lists from device and card to users. Pick whichever you can code without bugs under pressure.

How do I avoid the strictly greater than 75 bug?+

Don't divide. Compare sum > 75 * count with integers. Example 2 gives 150 versus 150, which must return false. A float division can work, but integer comparison removes any rounding doubt and the edge case is explicit.

What if every user in the ring has score 0?+

Then the non-trusted count is 0 and there's no average. Return false instead of dividing by zero. The problem says to return true only when the average is strictly above 75, so an empty set can't qualify.

How do I prepare for this in 48 hours?+

Write union-find with path compression from memory, then solve one connected-components problem with string keys. Then code this one end to end, parsing the comma-separated rows. Test Example 1, Example 2, an all-trusted ring, and a target user in a single-row ring.

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