Solve a Skyscraper puzzle efficiently
Company: Optiver
Role: Data Scientist
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Take-home Project
Quick Answer: This question evaluates understanding of constraint satisfaction and combinatorial search, testing competency in modeling Latin-square domains with visibility constraints, pruning and uniqueness verification, and algorithmic complexity analysis.
Constraints
- 3 <= N <= 7
- Each present clue value lies in 1..N; blanks are encoded as 0.
- Each of top/bottom/left/right, when present, is a list of length N; an omitted side is treated as all-blank.
- Heights inside the grid are exactly the integers 1..N with no repeats per row/column.
- Return any grid consistent with the clues, or None if none exists (uniqueness not required).
Examples
Input: (4, {'top': [0, 0, 1, 2], 'bottom': [0, 0, 0, 0], 'left': [0, 2, 0, 0], 'right': [0, 0, 0, 0]})
Expected Output: [[1, 2, 4, 3], [2, 4, 3, 1], [3, 1, 2, 4], [4, 3, 1, 2]]
Explanation: Under-constrained clue set (admits many grids). The solver returns the first consistent grid in canonical order; column 2 read top-down is [4,3,2,1] -> 1 visible matching top[2]=1, and row 1 [2,4,3,1] -> 2 visible matching left[1]=2.
Input: (4, {'top': [4, 3, 2, 1], 'bottom': [1, 2, 2, 2], 'left': [4, 3, 2, 1], 'right': [1, 2, 2, 2]})
Expected Output: [[1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2], [4, 1, 2, 3]]
Explanation: Fully clued. left[0]=4 and top[0]=4 force the first row and column to be strictly increasing; the cyclic Latin square satisfies every clue. Clues were derived programmatically from this target grid.
Hints
- A building is visible exactly when it is a new running maximum reading the line from the viewer's side, so the visible count = number of left-to-right maxima. Read a line from the opposite side by reversing it.
- Enumerate each row's permutations of 1..N and pre-filter by that row's left/right clues; then assign rows top-to-bottom, enforcing column AllDifferent and column (top/bottom) visibility.
- Keep rows in true index order 0..N-1 so a partial column [grid[0][c], grid[1][c], ...] is a genuine top-down prefix; otherwise top/bottom visibility is computed on a scrambled column. Cheap exact facts: clue N forces the line to be 1..N increasing, clue 1 forces the nearest cell to be N, and opposite-end clues on a line satisfy c_left + c_right <= N+1.