Code Editor with Block Shrink and Expand (Code Folding)
Jane StreetMachine Learning Engineer · Technical ScreenLast updated
This question evaluates a candidate's ability to model and manipulate indentation-based hierarchical structures, maintain nested visibility state for collapsed blocks, and map between original file lines and dynamic display numbering.
Implement the core of a code editor (similar to VS Code) that supports code folding: collapsing ("shrink") and restoring ("expand") indentation-based blocks of code.
Setup
The editor is initialized with a list of source-code lines. Indentation determines block structure, as in Python:
- Indentation is measured by the number of leading spaces, and every line's indentation is a multiple of 4 spaces.
- A line
Lis a block header if the line immediately after it has strictly greater indentation thanL. - The block owned by header
Lconsists of all consecutive lines afterLwhose indentation is strictly greater thanL's indentation. The block ends at the first subsequent line whose indentation is less than or equal toL's (or at the end of the file). - Blocks may be nested: a line inside a block may itself be a header of a smaller block.
Rendering
Implement a render() method that returns the currently visible lines, one string per line, formatted as:
<display_number> <marker><line content>
where:
display_numbernumbers the visible lines sequentially starting from 1 (hidden lines are skipped and do not consume a number).markeris+if the line is a block header, and the empty string otherwise.line contentis the original text of the line, including its leading indentation.
Operations
Implement two operations. Both take a display line number — a number as shown in the most recent render() output, not the original file line number.
shrink(d): if the visible line currently displayed at numberdis a block header, mark it collapsed. A collapsed header stays visible, but every line inside its block becomes hidden. If the line atdis not a block header, or its block is already collapsed, this is a no-op.expand(d): if the visible line currently displayed at numberdis a collapsed block header, mark it expanded again. Lines inside its block become visible except lines that are hidden because some nested header inside the block is itself still collapsed (each header keeps its own collapsed/expanded state).
In general, a line is visible if and only if none of the headers whose blocks contain it are collapsed.
Example
The editor is initialized with these 5 lines:
a = 1
for i in range(10):
print(i)
print(i ** 2)
b = 10
render() returns:
1 a = 1
2 + for i in range(10):
3 print(i)
4 print(i ** 2)
5 b = 10
After calling shrink(2), render() returns:
1 a = 1
2 + for i in range(10):
3 b = 10
Lines 3 and 4 of the original file (the body of the for loop) are hidden, and b = 10 is renumbered to display number 3. Calling expand(2) afterwards restores the original output.
Task
Implement a class:
class CodeEditor:
def __init__(self, lines: list[str]): ...
def shrink(self, d: int) -> None: ...
def expand(self, d: int) -> None: ...
def render(self) -> list[str]: ...
Constraints
1 <= number of lines <= 10^4, each line at most 200 characters.- Indentation is spaces only, always a multiple of 4, and the first line has indentation 0. A line's indentation is at most one level (4 spaces) deeper than the line before it.
- Up to
10^4totalshrink/expand/rendercalls. - Operations always receive a display number
dthat is valid for the most recent rendering (i.e.,1 <= d <=the current number of visible lines).
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.