5
\$\begingroup\$

I got this question during my practice interview.

Matrices - N Spiral Matrix

Prompt

Given an integer N, output an N x N spiral matrix with integers 1 through N.

Examples:

Input:  3

Output: [[1, 2, 3],
         [8, 9, 4],
         [7, 6, 5]]

Input: 1

Output: [[1]]

My solution is below:

function spiralMatrix(n) {
  const matrix = [];
  let counter = 1,
    rowMin = 0,
    rowMax = n - 1,
    colMin = 0,
    colMax = n - 1;

  for (let i = 0; i < n; i++) {
    matrix.push(new Array(n).fill(0));
  }

  while (rowMin <= rowMax && colMin <= colMax) {
    for (let col = colMin; col <= colMax; col++) {
      matrix[rowMin][col] = counter++;
    }
    rowMin++;
    for (let row = rowMin; row <= rowMax; row++) {
      matrix[row][colMax] = counter++;
    }
    colMax--;
    for (let col = colMax; col >= colMin; col--) {
      matrix[rowMax][col] = counter++;
    }
    rowMax--;
    for (let row = rowMax; row >= rowMin; row--) {
      matrix[row][colMin] = counter++;
    }
    colMin++;
  }

  return matrix;
}

console.log(spiralMatrix(10));
\$\endgroup\$
2
\$\begingroup\$

This code is well written;

Comments

  • You have no comments whatsoever, fortunately the code reads well

JSHint.com

  • Your code passes all checks, well done
\$\endgroup\$
2
\$\begingroup\$

Nice code. I have just one nitpick.

No need to declare all variables at the top of a function. It's good to declare variables right before they are used. In the posted code, the filling of matrix could go directly after its declaration, and the rest of the variables could be declared right before the loop that uses them. I mean like this:

  const matrix = [];
  for (let i = 0; i < n; i++) {
    matrix.push(new Array(n).fill(0));
  }

  let counter = 1,
    rowMin = 0,
    rowMax = n - 1,
    colMin = 0,
    colMax = n - 1;

  while (rowMin <= rowMax && colMin <= colMax) {
    // ...
\$\endgroup\$
  • \$\begingroup\$ Do you have any references that say it is good to declare variables right before they are used? This does not seem to follow any major coding styles guide. \$\endgroup\$ – konijn Feb 22 at 16:52
  • \$\begingroup\$ @konijn the book Code Complete takes about span and live time of variables. See it explained here: nikola-breznjak.com/blog/books/programming/… . Keeping these numbers low mitigates the mental burden for readers. \$\endgroup\$ – janos Feb 22 at 17:20
1
\$\begingroup\$

Rather than use row, and col, it is common to index a 2D array with x and y. x is column and y is row.

Rather than use for loops, you can reduce the noise using while loops inside the main loop.

The main exit condition is a little complex. You are counting the values with counter so why not just check its value while(counter < n ** 2) {

colMax and rowMax can be combined to just one value, same with colMin, and rowMin

The overhead of creating and filling each array before you start is negating the benefit of avoiding sparse arrays. The code would be simpler if you just push an array literal rather then a new n item array filled with 0.

Thus you end up with

function spiralMatrix(n) {
    var c = 1, min = 0, max = n - 1, x = 0, y = 0;
    const matrix = [];
    for (let i = 0; i < n; i++) { matrix.push([]) }
    while (c < n ** 2) {
        while (x < max) { matrix[y][x++] = c++ }
        while (y < max) { matrix[y++][x] = c++ }
        while (x > min) { matrix[y][x--] = c++ }
        min++;
        while (y > min) { matrix[y--][x] = c++ }
        max--;
    }
    matrix[y][x] = c;
    return matrix;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.