Document and Layer Operations
Reported by candidates from Figma's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Figma's September 2020 OA hands you up to 200000 operations over documents and layers, and the whole thing is a bookkeeping test dressed up as a design tool. It's a hash table problem with a sorted serialization at the end. Nothing here is hard, but it punishes sloppy data structures. If you scan a document's layers on every move or remove, you'll time out. If you blank on the layout, StealthCoder is the safety net running invisibly during the live OA. Still, this one is very doable in 48 hours once you see the two-map shape.
The problem
Process operations on a collection of documents and layers. Document IDs and layer IDs are lowercase ASCII strings, and layer IDs are globally unique.
Each operation has one of these forms:
["createDocument", documentId] creates an empty document.
["addLayer", documentId, layerId, value] creates a layer in the document.
["renameLayer", layerId, newValue] changes a layer's value.
["moveLayer", layerId, targetDocumentId] moves a layer to another document without changing its ID or value.
["removeLayer", layerId] removes a layer.
After all operations, return every document ordered by document ID. Serialize a document as documentId{layerId=value,...}, with its remaining layers ordered by layer ID. Include empty documents as documentId{}.
Function
processDocumentLayers(operations: String[][]) → String[]
Examples
Example 1
operations = [["createDocument","draft"],["addLayer","draft","title","hello"],["renameLayer","title","welcome"]]
return = ["draft{title=welcome}"]
The layer title remains in draft with its updated value.
Example 2
operations = [["createDocument","a"],["createDocument","b"],["addLayer","a","z","green"],["addLayer","a","m","blue"],["moveLayer","z","b"]]
return = ["a{m=blue}","b{z=green}"]
Moving z removes it from document a and preserves it in document b.
Example 3
operations = [["createDocument","doc"],["addLayer","doc","x","one"],["removeLayer","x"]]
return = ["doc{}"]
The document remains after its only layer is removed.
Constraints
1 <= operations.length <= 200000.
At most 100000 documents and 200000 layers are created.
Every document ID and layer ID is unique when created.
Every non-create operation references an existing document or layer as required.
IDs and values are non-empty lowercase ASCII strings of at most 40 characters and do not contain {, }, =, or ,.Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is two hash maps. One maps layerId to its current document and value. The other maps documentId to a set of its layer IDs. Layer IDs are globally unique, so every non-create operation is an O(1) lookup. Rename updates the value in the layer map. Move deletes the ID from the old document's set, adds it to the new one, and updates the owner. Remove deletes from both. Brute force fails because scanning all documents per operation with 200000 operations is far too slow. Sort only once at the end: document IDs, then each document's layer IDs. Pitfalls: forgetting empty documents must print as id{}, and updating the owner on a move. Use a string builder to avoid quadratic concatenation. If the live OA has you freezing on the structure, StealthCoder can supply the two-map layout as a hedge, but you can write it yourself in ten minutes.
If this hits your live OA and you blank, StealthCoder solves it in seconds, invisible to the proctor.
You can drill Document and Layer Operations 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 Figma's OA.
Figma 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.
Document and Layer Operations FAQ
How hard is the Figma Document and Layer Operations question really?+
Easy to medium. There's no clever algorithm, just clean state management. The difficulty is choosing structures so every operation is O(1) and then serializing correctly. Candidates lose points on edge cases like empty documents and stale layer ownership after a move, not on the logic.
What's the trick to avoid timing out?+
Keep a layerId to (documentId, value) map so you never search for a layer. Keep a documentId to set-of-layerIds map for membership. Every operation then touches a constant number of entries. Defer all sorting to the very end, once per document.
Do I need sorted maps during processing?+
No. Use plain hash maps while processing and sort at the end. Sorted maps add log factors to every operation for nothing. Sort document IDs once, then sort each document's layer IDs when you serialize. Total sort cost is bounded by the layer count.
What edge cases should I test before submitting?+
A document with all layers removed must print as id{}. A layer moved then renamed must show the new value in the new document. A layer moved twice should end in the last target. Also check a document created but never given layers still appears.
How do I prepare for this in 48 hours?+
Write it once from scratch with two hash maps and time yourself. Then practice the serialization format, since a stray comma or missing brace fails every test. Skim similar simulation and design-style problems that process an operations list into a final state.