Collect Pins from Reachable Boards
Company: Pinterest
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Take-home Project
# Collect Pins from Reachable Boards
The interview report names a board-and-pin coding problem whose intended approach was breadth-first search but does not preserve the full prompt. Use the following literal graph contract as a faithful practice interpretation.
```python
def collect_reachable_pins(
start_board: str,
boards: list[list[object]],
) -> list[str]:
...
```
Each board record is `[board_id, pins, child_boards]`, where all three identifiers are strings, `pins` is a list of pin IDs in display order, and `child_boards` is a list of board IDs in traversal order. The board graph can contain shared children and cycles.
Starting at `start_board`, visit boards in breadth-first order. Enqueue child boards in the order listed by their first processed parent. Process each board at most once. Return each pin the first time it is encountered, preserving the pin order within a board and omitting later duplicate pin IDs. Return `[]` when `start_board` is not present.
## Example
```text
Input:
start_board = "home"
boards = [
["home", ["p1"], ["travel", "food"]],
["travel", ["p2", "p3"], ["shared"]],
["food", ["p3", "p4"], ["shared"]],
["shared", ["p5"], ["home"]]
]
Output: ["p1", "p2", "p3", "p4", "p5"]
```
## Constraints and Errors
- `0 <= len(boards) <= 200_000`
- The total number of pin and child references is at most `500_000`.
- Board IDs are unique and nonempty. Pin IDs are nonempty.
- Every child-board reference must name a supplied board.
- A malformed record, non-string identifier, duplicate board ID, empty identifier, or unknown child reference raises `ValueError`.
- Validate the full graph before traversal and do not mutate the input.
## Hints
- Build a board lookup once, then keep separate sets for visited boards and emitted pins.
- Mark a board visited when it is enqueued, not when it is dequeued, to avoid duplicate queue entries.
- A FIFO queue plus listed child order makes the output deterministic.
Quick Answer: Traverse a directed graph of boards in deterministic breadth-first order and collect each reachable pin only on its first appearance. Handle cycles and shared children with separate visited-board and emitted-pin sets after validating every record and reference.
Validate a directed board graph, traverse reachable boards from a start ID in breadth-first order using listed child order, and return each pin the first time encountered while preserving per-board pin order.
Constraints
- Board IDs are unique nonempty strings.
- Every child reference names a supplied board.
- Graphs may contain cycles and shared children.
- Pin IDs are nonempty strings.
- The full graph is validated before traversal.
Examples
Input: {'start_board':'home','boards':[['home',['p1'],['travel','food']],['travel',['p2','p3'],['shared']],['food',['p3','p4'],['shared']],['shared',['p5'],['home']]]}
Expected Output: ['p1', 'p2', 'p3', 'p4', 'p5']
Explanation: The supplied graph combines BFS, a shared child, and a cycle.
Input: {'start_board':'x','boards':[]}
Expected Output: []
Explanation: A missing start returns empty.
Hints
- Build the board lookup once.
- Mark boards visited when enqueued.
- Use a separate set for pins already emitted.