Versioned Social Network
Reported by candidates from OpenAI's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
OpenAI reported this one in July 2026, and it looks friendlier than it is. A versioned social network with FOLLOW, UNFOLLOW, SNAPSHOT and IS_FOLLOWING sounds like a graph problem. It's really a hash map of per-edge histories plus a binary search. The OA has strict complexity limits, so copying the graph per snapshot fails fast. If you've got an invite in your inbox, the whole thing comes down to one edge case: several changes to the same edge between two snapshots. If you blank mid-assessment, StealthCoder runs invisibly as a safety net and surfaces the approach live.
The problem
A directed social network has n users numbered from 0 to n - 1. A relationship u -> v means that user u follows user v. Relationships change over time. The network can create immutable snapshots and later answer whether a relationship existed at a particular snapshot. A snapshot must not copy the entire graph. Instead, keep a history of changes for each directed relationship. Every snapshot includes all preceding updates. Later updates never change an earlier snapshot. If the same relationship changes more than once before the next snapshot, that snapshot records its state after the last such change. Operations Process the commands in order: FOLLOW u v: add the directed relationship u -> v. The relationship is guaranteed to be inactive immediately before this command. UNFOLLOW u v: remove the directed relationship u -> v. The relationship is guaranteed to be active immediately before this command. SNAPSHOT: save the current network state. Snapshot IDs start at 0 and increase by 1. Append the new ID to the output. IS_FOLLOWING u v snapshot_id: append true if u followed v when that snapshot was created; otherwise append false. A relationship that had not yet been followed is inactive. Only SNAPSHOT and IS_FOLLOWING produce output. Return their outputs in command order as strings. Performance Requirements FOLLOW, UNFOLLOW, and SNAPSHOT must each run in expected O(1) time. A historical query for one relationship must run in O(log h) time, where h is the number of recorded changes for that relationship. The total auxiliary space must be O(c), where c is the number of follow and unfollow commands. Further Interview Stages The reports also described listing relationships at a snapshot, recommending friends, and comparing two snapshots. The exact recommendation rule and snapshot-difference output were not provided. Function processVersionedSocialNetwork(n: int, operations: String[]) → String[] Examples Example 1 n = 4 operations = ["FOLLOW 0 1", "FOLLOW 0 2", "SNAPSHOT", "UNFOLLOW 0 1", "SNAPSHOT", "IS_FOLLOWING 0 1 0", "IS_FOLLOWING 0 1 1", "IS_FOLLOWING 0 2 1"] return = ["0", "1", "true", "false", "true"] Snapshot 0 contains both relationships from user 0. Snapshot 1 is created after 0 unfollows 1, while the relationship 0 -> 2 remains active. Example 2 n = 3 operations = ["FOLLOW 1 2", "UNFOLLOW 1 2", "FOLLOW 1 0", "SNAPSHOT", "IS_FOLLOWING 1 2 0", "IS_FOLLOWING 1 0 0"] return = ["0", "false", "true"] Both changes to 1 -> 2 occur before the first snapshot, so its final state in snapshot 0 is inactive. The relationship 1 -> 0 is active. Example 3 n = 3 operations = ["SNAPSHOT", "FOLLOW 2 1", "SNAPSHOT", "UNFOLLOW 2 1", "FOLLOW 2 1", "SNAPSHOT", "IS_FOLLOWING 2 1 0", "IS_FOLLOWING 2 1 1", "IS_FOLLOWING 2 1 2"] return = ["0", "1", "2", "false", "true", "true"] The relationship is absent in snapshot 0 and present in snapshot 1. It is removed and restored before snapshot 2, so its snapshot 2 state is active. Constraints 1 <= n <= 100000 1 <= operations.length <= 200000 0 <= u, v < n and u != v Every FOLLOW targets an inactive relationship. Every UNFOLLOW targets an active relationship. Every IS_FOLLOWING references a snapshot that has already been created. Commands contain single spaces between tokens. At least one command produces output.
Reported by candidates. Source: FastPrep
Pattern and pitfall
Key the map on the pair (u, v), for example u * n + v as a long. Each key stores a list of (snapshotId, state) entries. On FOLLOW or UNFOLLOW, use the current snapshot counter as the version. If the last entry already has that version, overwrite its state. Otherwise append a new entry. That overwrite is the edge case. Example 2 tests it: follow then unfollow before snapshot 0 must read false, not true. SNAPSHOT just returns the counter and increments it. For IS_FOLLOWING, binary search the list for the last entry with version <= snapshot_id. No entry means false. Otherwise return its state. Pitfalls: appending duplicate versions, which breaks the search, and an off-by-one where a change made after snapshot k leaks into k. Pair it with the counter and you get O(1) updates, O(log h) queries and O(c) space. If the logic slips under pressure, StealthCoder is the hedge on the live OA.
StealthCoder is the hedge for the one pattern you didn't drill. It runs invisibly during the screen share.
You can drill Versioned Social Network 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. If you're reading this with an OA window open, you're who this was built for.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass OpenAI's OA.
OpenAI reuses patterns across OAs. If you're reading this with an OA window open, you're who this was built for. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Versioned Social Network FAQ
What's the trick in the OpenAI Versioned Social Network problem?+
Store a history per edge, not per snapshot. Use a hash map from (u, v) to a sorted list of (version, state). Queries binary search that list for the last version at or before the snapshot ID. No copying, so the O(1) update and O(c) space requirements hold.
How do I handle multiple changes to one edge before a snapshot?+
Overwrite. If the edge's last history entry has the current snapshot counter as its version, update its state instead of appending. Then each version appears once per edge, and the snapshot sees only the final state. Example 2 checks exactly this.
How hard is this really?+
Medium. There's no tricky algorithm, just a hash map and binary search. The difficulty is the strict complexity wording and the same-version overwrite. Candidates who copy state per snapshot or scan the history linearly miss the stated bounds.
What should IS_FOLLOWING return when the edge was never touched?+
false. A missing key means the edge was never followed. Also return false if every recorded version is greater than the queried snapshot ID, meaning the first follow happened after that snapshot. Example 3 shows this for snapshot 0.
How do I prepare in 48 hours?+
Write this once from scratch. Use a long key for the pair, per-edge arrays of versions and states, and a manual lower-bound or upper-bound search. Test the three examples, especially the same-version overwrite. The later stages in the report (listing, recommendations, diffs) weren't fully specified, so don't prep for them.