Rich Text Parser Part 3 (Depth Tokens)
Learn this problemProblem statement
π Source note, July 7, 2026: This set reconstructs a real Figma MLE full-time coding screen, shared first-hand by a candidate. The depth-token format and its example come straight from that account. The candidate's memory of this final part was fuzzier than Parts 1 and 2, so call it roughly a 90% match. The original relied on asking the interviewer clarifying questions, so FastPrep made the rules explicit (starting depth, depth jumps, sibling merging) and enriched the tests with boundary cases the live session never reached. If you know the fuller version, we'd love to hear it. Thank you! π
π Hi there! The description you are currently reading is one part of a 3-part Figma interview set. It is highly recommended to read ALL THE PARTS before coding as parts build on top of each other π³
At Figma, documents are stored as nested structures: a paragraph can contain text runs and nested groups, which can themselves contain more groups. You are working with a small text format that describes structures like this. This set reconstructs a real ~45-minute Figma coding screen, part by part.
Part 3. This was the final twist of the real interview. After the Part 2 parser passed, the interviewer swapped the tokenizer for a different implementation and asked for the same result. The new tokenizer returns a flat list in which every word is preceded by its nesting depth: tokenize("(a,(b),c)") now returns [1, 'a', 2, 'b', 1, 'c']. There are no bracket tokens anymore.
Implement readRichText(tokens) that produces the same serialized nested structure that Part 2 produced, from this new token format. On FastPrep the flat list arrives as string tokens: depths appear as strings such as "1", each followed by its word.
Rules of the depth encoding.
- depths are positive integers; the first depth may be greater than
1 - between consecutive words the depth may rise or fall by more than
1: each unit of rise opens one new group, each unit of fall closes one - consecutive words at the same depth are siblings in the same group, and a word that returns to a still-open depth joins that open group
- this encoding cannot represent empty groups, so none appear
Output format. Return the parsed document as a Python-style list string:
- a group serializes as
[β¦]with children joined by a comma and a single space - words are wrapped in single quotes
- the return value is the serialization of the document: the list of all top-level items. A document that consists of one group therefore starts with two brackets, e.g.
[['a', 'b', 'c']]
In Python, str(nested_list) produces exactly this format.
Function
readRichText(tokens: String[]) β StringExamples
Example 1
tokens = ["1", "a", "1", "b", "1", "c"]return = "[['a', 'b', 'c']]"All words have depth 1, so they belong to the same top-level group: ['a', 'b', 'c']. The full parsed document is [['a', 'b', 'c']].
Example 2
tokens = ["1", "a", "2", "b", "1", "c"]return = "[['a', ['b'], 'c']]"This is the Part 3 source example for tokenize("(a,(b),c)"). The word b has depth 2, so it becomes a nested group between a and c.
Example 3
tokens = ["3", "a", "2", "b", "1", "c"]return = "[[[['a'], 'b'], 'c']]"This corresponds to the source example read_rich_text(tokenize("(((a)b)c)")) from Part 2. The first depth is 3, so a sits inside three groups; the depths then fall to 2 and 1, closing one level each time. Together with the outer document list the answer has four leading brackets.
Example 4
tokens = ["1", "a", "3", "b"]return = "[['a', [['b']]]]"Only words carry depth labels, so the depth can jump from 1 straight to 3: two new groups open at once and b lands inside both.
Constraints
0 <= tokens.length <= 5000, always an even number: alternating depth and word- depths are decimal strings between
1and50 - words are lowercase alphanumeric with at most 10 characters