Katkat

Clockwise Spiral Matrix Traversal That Turns at Blocked Cells

PinduoduoSoftware Engineer · Technical Screen

Last updated

Return the values of a matrix in clockwise spiral order starting from the top-left cell, then extend the walk so that blocked cells force clockwise turns and can end it early. Tests precise grid simulation, direction rotation, visited and boundary checks, and an unambiguous stopping rule.

Given an m x n matrix of integers, return its values in clockwise spiral order: start at the top-left cell, go right along the top row, down the right column, left along the bottom row and up the left column, then keep circling inward until every cell has been output.

Follow-up: some cells are blockers. The walk never enters a blocker. When the next cell in the current direction is a blocker, the walk turns clockwise (to its right), just as it does at the edge of the matrix or in front of a cell it has already visited. Return the values in the order the walk visits them. A matrix with no blockers gives the plain spiral order, so one function answers both parts.

The report does not say when the blocker walk stops, or what happens when a single right turn is not enough; the rules below fix both.

Function Signature

def spiral_with_blockers(matrix: list[list[int]], blocked: list[list[int]]) -> list[int]:

blocked lists the blocker cells as [row, col] pairs.

Rules

  • Row 0 is the top row and column 0 is the leftmost column. Right leads from (r, c) to (r, c + 1), down to (r + 1, c), left to (r, c - 1) and up to (r - 1, c). Turning clockwise goes from right to down, from down to left, from left to up, and from up to right.
  • A cell is available if it lies inside the matrix, is not a blocker, and has not been visited yet.
  • The walk starts on (0, 0) facing right. (0, 0) counts as visited, and its value is the first output.
  • At each step, look at the next cell in the current direction. If it is available, move into it and output its value. If not, turn 90 degrees clockwise and look again, checking at most four directions in total. The first direction that leads to an available cell becomes the current direction, and the walk moves one cell in it.
  • If none of the four directions leads to an available cell, the walk ends. Open cells it never reached are not output.
  • Blockers are never output.

Constraints

  • 1 <= m, n <= 100, where m = len(matrix) and n = len(matrix[0]); every row has length n.
  • -10^9 <= matrix[r][c] <= 10^9
  • 0 <= len(blocked) <= m * n - 1
  • Every pair in blocked lies inside the matrix, the pairs are distinct, and [0, 0] is never a blocker.

Examples

Example 1

Input: matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], blocked = []
Output: [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7]

With no blockers this is the plain spiral: the outer ring, then 6 and 7 in the middle row.

Example 2

Input: matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], blocked = [[1, 1]]
Output: [1, 2, 3, 4, 8, 12, 11, 10, 9, 5]

The walk matches Example 1 until it reaches 5 at (1, 0) facing up. From there, up leads to the visited (0, 0), right to the blocker (1, 1), down to the visited (2, 0), and left out of the matrix, so the walk ends. The open cell holding 7 is never reached.

Example 3

Input: matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], blocked = [[0, 1]]
Output: [1, 4, 7, 8, 9, 6, 3]

At (0, 0) the blocker on the right turns the walk down through 4 to 7. At (2, 0) facing down, down and left are outside the matrix and up is visited, so after three clockwise turns the walk faces right and moves through 8 to 9. At (2, 2) facing right, right and down are outside and left is visited, so it turns to face up and moves through 6 to 3. At (0, 2) facing up, up and right are outside, down is visited and left is the blocker, so the walk ends without visiting 5.