Quick Overview

Implement a stateful text editor that grows from character insertion and deletion to cursor movement, newlines, and ordered print snapshots. The prompt defines deterministic boundary, backspace, and vertical-movement behavior for a later portable console implementation.

Process Stateful Text Editor Commands

Company: Datology

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

# Process Stateful Text Editor Commands Implement `process_editor(operations)`. The editor starts with one empty line and a cursor at row `0`, column `0`; a column identifies a gap between characters. Process the operations in order and return every document snapshot produced by `PRINT`. Supported operations are: - `"TYPE c"`: insert the single printable ASCII character `c` at the cursor, then move the cursor one column right. - `"BACKSPACE"`: delete the character immediately left of the cursor. At column `0`, join the current line onto the previous line when one exists; at the start of the document, do nothing. - `"LEFT"`: move one character left. From column `0` of a nonfirst line, move to the end of the previous line; at the start of the document, do nothing. - `"RIGHT"`: move one character right. From the end of a nonlast line, move to column `0` of the next line; at the end of the document, do nothing. - `"NEWLINE"`: split the current line at the cursor and move the cursor to column `0` of the new line. - `"UP"` or `"DOWN"`: move to the adjacent line when it exists and clamp the column to that line's length. The editor does not retain a separate preferred column. - `"PRINT"`: append the entire document, with lines joined by the newline character, to the result. These boundary rules are explicit pedagogical assumptions because the source specifies the editor stages but not their edge semantics. ## Function Contract `process_editor(operations: list[str]) -> list[str]` ## Constraints - `0 <= len(operations) <= 200000` - Each `TYPE` operation contains exactly one printable ASCII character other than a newline. - The total number of typed characters is at most `200000`. - Output snapshots are returned in the same order as their `PRINT` operations. ## Examples ### Example 1 ```text Input: ["TYPE a", "TYPE b", "LEFT", "TYPE X", "PRINT", "RIGHT", "BACKSPACE", "PRINT"] Output: ["aXb", "aX"] ``` The inserted `X` appears between `a` and `b`; the later backspace removes `b`. ### Example 2 ```text Input: ["TYPE a", "TYPE b", "NEWLINE", "TYPE c", "TYPE d", "UP", "TYPE X", "PRINT", "DOWN", "LEFT", "BACKSPACE", "PRINT"] Output: ["abX\ncd", "abX\nd"] ``` Moving up clamps the cursor to the end of `ab`; after returning to the second line, backspace removes `c`.

Overview: Implement a stateful text editor that grows from character insertion and deletion to cursor movement, newlines, and ordered print snapshots. The prompt defines deterministic boundary, backspace, and vertical-movement behavior for a later portable console implementation.

Read the full Datology Software Engineer interview experience this question came from

Implement process_editor(operations). The document starts as one empty line with the cursor at row 0, column 0, where a column is a gap between characters. TYPE inserts its one printable non-newline ASCII character and advances the cursor. BACKSPACE deletes immediately left, or at column 0 joins the current line onto the previous line with the cursor at the join; it does nothing at document start. LEFT and RIGHT move one character and cross line boundaries as specified, doing nothing at document boundaries. NEWLINE splits at the cursor and moves to column 0 of the new line. UP and DOWN enter an adjacent line at the current column clamped to that line's length, without retaining a preferred column. PRINT returns the entire document with newline separators. Return all PRINT snapshots in operation order.

Constraints

  • 0 <= operations.length <= 200,000
  • The editor starts with one empty line and cursor (0, 0).
  • Every operation is TYPE c, BACKSPACE, LEFT, RIGHT, NEWLINE, UP, DOWN, or PRINT.
  • Each TYPE contains exactly one printable ASCII character other than newline.
  • The total number of typed characters is at most 200,000.
  • UP and DOWN clamp the actual column and do not preserve a preferred column.
  • PRINT snapshots join document lines with the newline character and retain operation order.

Examples

Input: (['TYPE a', 'TYPE b', 'LEFT', 'TYPE X', 'PRINT', 'RIGHT', 'BACKSPACE', 'PRINT'],)

Expected Output: ['aXb', 'aX']

Explanation: The first source example checks insertion at an interior gap and ordinary backspace.

Input: (['TYPE a', 'TYPE b', 'NEWLINE', 'TYPE c', 'TYPE d', 'UP', 'TYPE X', 'PRINT', 'DOWN', 'LEFT', 'BACKSPACE', 'PRINT'],)

Expected Output: ['abX\ncd', 'abX\nd']

Explanation: The second source example checks splitting, vertical clamping, and a later deletion.

Hints

  1. A cursor is naturally represented by two stacks holding text before and after its gap.
  2. Store lines in a linked sequence so splitting and joining do not shift an array of rows.

Loading coding console...

Show the approach

Approach

Represent every line with a gap: a left character stack in document order and a right stack in reverse order. The cursor column is the left-stack length. TYPE, ordinary BACKSPACE, LEFT, and RIGHT move only a stack-end character. Keep the lines in a doubly linked sequence so NEWLINE inserts after the current line and a boundary BACKSPACE removes the current line without shifting other lines. UP and DOWN move to the neighboring line and transfer characters between that line's stacks until its gap reaches the clamped column. PRINT walks the line sequence and renders left plus reversed right. Splitting transfers the current suffix to a new line; joining first puts the previous gap at its end, then stores the removed line as its right suffix, which places the cursor exactly at the join.

Time complexity:
O(n + V + S), where n is the operation count, V is the total number of character transfers needed to reposition gaps on vertical moves or joins, and S is the total size of all emitted snapshots.
Space complexity:
O(T + L + S), where T is the current typed document size, L is the number of lines, and S is the returned snapshot content.