Parse Parent-Child Task Records and Render Them as a Connector Tree
StripeSoftware Engineer · Technical ScreenLast updated
A multi-part coding exercise that parses root and child task records, linked by parent identifiers, into a parent-child map and renders the hierarchy as a text tree with branch connectors for middle and last children. It tests careful reading of a long specification, robust tree building and exact output formatting.
You receive a list of task records and must rebuild the hierarchy of tasks and subtasks they describe, then print it as a text tree. The specification is long and the output format is strict, so reading carefully matters as much as the code. The exercise is split into parts; the first two are below.
There are two kinds of records:
- Root records contain the fields
timestamp,task,task_idandtask_name. - Child records contain the fields
timestamp,subtask,parent_id,task_idandtask_name. Theparent_idof a child is thetask_idof its parent.
Clarifying Questions
- Is the result returned as one string or printed line by line, and is it compared character for character?
- How many records can there be, and how deep can the nesting go?
Part 1 — Parse the records into a parent-child map
Parse the records into a structure that maps every task to its child tasks and identifies the root tasks.
Clarifying Questions for this Part
- In what form do the records arrive: parsed objects, JSON lines or another text format?
- What do the
taskandsubtaskfields hold, and is a record's kind decided by them or by the presence ofparent_id? - Can a child have children of its own?
- What should happen to a record whose
parent_idmatches no task, or to two records that share atask_id?
What This Part Should Cover
- A map from each parent to its children, plus the list of roots, built independently of input order
- Handling of orphans, duplicate identifiers and cycles in the parent links
- Time and space complexity of the build
Part 2 — Render the tree with connectors
Print the hierarchy. A root node is printed without any leading connector. A child that is not the last among its siblings is printed after ├─, and the last child in a sibling group is printed after └─. For a root with two children, the output has this shape (the labels are placeholders):
Root task
├─ First child
└─ Last child
Clarifying Questions for this Part
- What text is printed for each node: the task name, the identifier, or both?
- In what order are siblings and roots printed: by timestamp, by input order or by identifier?
- For grandchildren and deeper nodes, what indentation goes in front of the connector?
What This Part Should Cover
- Deterministic sibling ordering and correct detection of the last child
- Correct prefixes at every depth, not only for the direct children of a root
- A traversal that is safe for deep trees, and its cost
Hints
Hint 1
Input order: Do not assume that a parent's record appears before the records of its children.
Hint 2
Two separate decisions: A line's connector depends only on the node's position among its siblings. What goes in front of the connector on deeper lines is a separate decision that depends on the node's ancestors.
Follow-up questions
- How would you print only the subtree rooted at a given task?
- If records keep arriving over time, how would you keep the tree up to date and re-render only what changed?
- How would you detect and report a cycle in the parent links?
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.