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));
asked Feb 21, 2019 at 2:01
\$\endgroup\$

3 Answers 3

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
answered Feb 21, 2019 at 16:59
\$\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) {
 // ...
answered Feb 21, 2019 at 19:04
\$\endgroup\$
2
  • \$\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\$ Commented Feb 22, 2019 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\$ Commented Feb 22, 2019 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;
}
answered Feb 22, 2019 at 16:34
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.