Reported September 2026
Affirmhash table

Propagating Fraud Detector

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

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

Affirm reported this one in September 2026, and it looks scarier than it is. Strip the fraud story and it's a single pass over the events with a hash set of (field, value) pairs. No graph, no union-find, no backtracking. If you've got an OA invite and 48 hours, this is a problem you can solve cleanly once you see the shape. StealthCoder sits invisibly on your screen as a safety net if you blank mid-assessment, but the logic below should be enough to carry you.

The problem

Process a batch of events in order while maintaining a set of suspicious personally identifiable information (PII) entries. Each row of events contains exactly five strings: event type, address, phone number, email address, and Social Security number. An empty string means the field is absent. PII identity includes its field, so equal text in different fields represents different entries.
For fraud_flag, add every non-empty PII entry to the suspicious set and append an empty string to the result.
For underwriting, append 1 when at least one non-empty PII entry is already suspicious; otherwise append 0. If the event is suspicious, add all of its non-empty PII entries to the set so suspicion can propagate. A clean underwriting event does not change the set.
Return one result string per event in the original order.

Function
detectPropagatingFraud(events: String[][]) → String[]

Examples
Example 1
events = [["fraud_flag","1 Main St","111","",""],["underwriting","2 Oak St","111","b@example.com","S2"],["underwriting","3 Pine St","333","b@example.com","S3"],["underwriting","4 Elm St","444","d@example.com","S4"]]
return = ["","1","1","0"]
The fraud flag seeds phone 111. The second event is suspicious through that phone and adds all of its PII, including email b@example.com. That email makes the third event suspicious. The fourth event shares nothing suspicious.
Example 2
events = [["underwriting","A","P","",""],["fraud_flag","B","Q","",""],["underwriting","A","Q","",""],["underwriting","C","P","",""]]
return = ["0","","1","0"]
The first underwriting event is clean, so it does not seed address A or phone P. The fraud flag seeds phone Q. The third event is suspicious through Q and propagates address A, but it still does not add phone P. The fourth event shares only P and therefore remains clean.
Example 3
events = [["fraud_flag","same","","",""],["underwriting","","same","",""]]
return = ["","0"]
The first row marks the address value suspicious. The equal text in the second row is a phone value, so it is a different PII identity and does not match.

Constraints
1 <= events.length <= 100000
events[i].length == 5
events[i][0] is either underwriting or fraud_flag.
Every non-empty PII value has length from 1 through 100.
Every event contains at least one non-empty PII field.

Reported by candidates. Source: FastPrep

Pattern and pitfall

The trick is that events are processed in order, so suspicion only flows forward. That kills the urge to build a graph. Keep one set of strings, keyed by field index plus the value, like "2:111" for phone. For fraud_flag, add every non-empty field and append an empty string. For underwriting, check whether any non-empty field is already in the set. If yes, add all its non-empty fields and output "1". If no, output "0" and touch nothing. The classic pitfalls are three. Keying by value alone, which breaks Example 3. Adding PII from a clean underwriting event, which breaks Example 2. Adding fields while you check, which can corrupt the answer. Check first, then add. With 100000 events and 5 fields each, that's O(n) time. If you freeze on the live OA, StealthCoder can hand you this structure fast, but you can write it in ten lines.

If you see this problem in your OA tomorrow, the play is to recognize the pattern in 30 seconds. StealthCoder buys you that recognition.

If this hits your live OA

You can drill Propagating Fraud Detector 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 passed his OA cold and still thinks the filter is broken.

Get StealthCoder

Related leaked OAs

⏵ The honest play

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

Affirm reuses patterns across OAs. Built by an Amazon engineer who passed his OA cold and still thinks the filter is broken. Works on HackerRank, CodeSignal, CoderPad, and Karat.

Propagating Fraud Detector FAQ

What's the trick in Propagating Fraud Detector?+

Treat it as a forward simulation with one hash set. Key each entry by field position plus value so the same text in different fields stays distinct. Check any-match first, then add all non-empty fields only if the event is suspicious or a fraud_flag.

Do I need union-find or a graph?+

No. Events are processed in order and suspicion only propagates forward from the moment an event is flagged. Earlier clean events never get retroactively marked. A single set gives you the correct answer, and union-find would add complexity and likely a wrong answer on Example 2.

Why does Example 2 return 0 for the first event?+

The first underwriting event is clean when it arrives, since nothing suspicious exists yet. A clean underwriting event doesn't change the set, so its address A and phone P are never seeded. Later events sharing only P stay clean.

What's the time complexity and will it pass 100000 events?+

It's O(n) with five fields per event, so at most about 500000 set lookups and inserts. Hash set operations on strings up to length 100 are fine. Just avoid rebuilding strings or scanning the whole set per event.

How do I prepare for this in 48 hours?+

Write it once from scratch in your strongest language. Then test the three examples, especially the cross-field case and the clean-event case. Also practice other single-pass hash set simulation problems so the pattern feels automatic when the assessment opens.

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

OA at Affirm?
Invisible during screen share
Get it