Parse, Validate, and Repair Markdown Formatting
Reported by candidates from Figma's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Figma flagged this one in June 2024, and the constraint is the first thing to read: text can be 200000 characters long, so anything that rescans or rebuilds the string per marker is dead on arrival. It's a single-pass string scan with a tiny stack of open formats. You tokenize markers, decide open, close, or drop, and emit two outputs at once. The rules are fiddly but fully deterministic. If you blank on the *** handling during the live OA, StealthCoder is the safety net sitting invisibly on your screen.
The problem
Process a restricted Markdown string with three formatting markers: * for italic text, rendered as [em]...[/em]. ** for bold text, rendered as [strong]...[/strong]. ~~ for strikethrough text, rendered as [del]...[/del]. Require properly nested formatting. Recognize two-character markers before a single *. A run of *** closes whichever of nested bold and italic formatting is currently on top, then closes the other with the remaining marker. Repair invalid input deterministically: If the recognized marker matches the top of the open-marker stack, it closes that format. If the same marker is open deeper in the stack, the current crossing marker is removed. Otherwise the marker opens a new format. After the scan, append closing markers for every still-open format from innermost to outermost. Return three strings: the tagged text rendered from the repaired Markdown, "true" exactly when no marker was removed or appended, and the repaired Markdown. Function processMarkdown(text: String) → String[] Examples Example 1 text = "I *really* like this" return = ["I [em]really[/em] like this","true","I *really* like this"] The italic markers are already balanced and properly nested. Example 2 text = "**Bold and *italic*** plus ~~old~~" return = ["[strong]Bold and [em]italic[/em][/strong] plus [del]old[/del]","true","**Bold and *italic*** plus ~~old~~"] The italic section is nested inside bold formatting, and the trailing three stars close italic before bold. Example 3 text = "*one **two* three**" return = ["[em]one [strong]two three[/strong][/em]","false","*one **two three***"] The crossing italic marker is removed. Bold then closes normally, and the missing outer italic closer is appended. Constraints 0 <= text.length <= 200000. The input contains no HTML-sensitive characters <, >, or &. Every * and ~ belongs to a recognized marker; literal marker escaping and empty formatted spans are outside this exercise. Under the repair rules, at most the three distinct formatting kinds can be open at once.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is one left-to-right pass with a stack holding at most three kinds: em, strong, del. At each position, check for ** and ~~ before a single *. Then apply the three rules in order: top matches means close, same marker deeper in the stack means drop the crossing marker, otherwise push. Build the tagged output and the repaired Markdown in parallel with lists, then join once at the end. Never concatenate strings in a loop. The pitfall is ***. It's a closer for whatever is on top, then the remaining marker closes the other one, so you treat it as a ** and a * in the right order depending on the stack top. Track a flag for any removal or appended closer. After the scan, pop the stack and append closers innermost first. If the *** case slips under time pressure, StealthCoder can cover you during the live OA.
Drill it cold or hedge it with StealthCoder. Either way, don't walk into the OA hoping you remember the trick.
You can drill Parse, Validate, and Repair Markdown Formatting 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. Made for the candidate who got the OA invite this morning and has 72 hours, not six months.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Figma's OA.
Figma reuses patterns across OAs. Made for the candidate who got the OA invite this morning and has 72 hours, not six months. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Parse, Validate, and Repair Markdown Formatting FAQ
How hard is this Figma Markdown problem really?+
Medium on paper, but the edge cases make it feel harder. The algorithm is a linear scan with a stack of at most three items. The difficulty is following the repair rules exactly, especially *** and crossing markers. Trace the three examples by hand before coding.
What's the trick to handling ***?+
Treat it as two markers resolved against the stack. If the top is strong, the ** part closes it and the * closes italic. If the top is em, the * closes it first, then ** closes bold. Check the stack top, then decide how to split the three stars.
Why does 200000 characters matter?+
It rules out quadratic work. Don't use string concatenation in a loop or slice the text repeatedly. Use an index pointer, a small stack, and lists of output pieces joined at the end. The whole thing should run in O(n) time.
When do I remove a marker versus open a new one?+
Check the stack in order. If the marker equals the top, close it. If it appears deeper in the stack, it's a crossing marker, so drop it from both outputs and flag the input as repaired. If it isn't open anywhere, push it and emit the opening tag.
How do I prepare for this in 48 hours?+
Write the scanner once from scratch and run all three examples by hand. Then add your own cases: unclosed del, nested all three, crossing del and bold, and an empty string. Confirm the true/false flag only flips on removals or appended closers.