DEV Community

Discussion on: Spiral Matrix in Javascript

Collapse
peerreynders profile image
peerreynders • Edited on
//           y
//           |
//    16 15 14 13 12
//    17  4  3  2 11
// -- 18  5  0  1 10 --- x
//    19  6  7  8  9
//    20 21 22 23 24
//           |
//
// Given coordinates (x,y) return "spiral index". Source:
// https://stackoverflow.com/questions/9970134/get-spiral-index-from-location/9971465#9971465
//
function spiralIndex(x, y) {
  const y2 = y * y;
  const x2 = x * x;
  if (y2 >= x2) {
    const value = 4 * y2 - y - x;
    return y >= x ? value : value - 2 * (y - x);
  }
  const value = 4 * x2 - y - x;
  return y >= x ? value : value + 2 * (y - x);
}

function makeToValue(n) {
  const n2 = n * n;
  if (n % 2 === 0) {
    const baseY = n / 2;
    const baseX = baseY - 1;
    return (row, column) => n2 - spiralIndex(column - baseX, baseY - row);
  }

  const base = (n - 1) / 2;
  return (row, column) => n2 - spiralIndex(base - column, row - base);
}

function spiralMatrix(n) {
  const toValue = makeToValue(n);
  const config = { length: n };
  return Array.from(config, (_vr, row) =>
    Array.from(config, (_vc, column) => toValue(row, column))
  );
}

console.log(spiralMatrix(3)); // [[1, 2, 3], [8, 9, 4], [7, 6, 5]]
console.log(spiralMatrix(4)); // [[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]
Enter fullscreen mode Exit fullscreen mode

This seems to work as well

function spiralMatrix(n) {
  if (n < 1) return [];

  const matrix = Array.from({ length: n }, (_v, _i) => []);
  let row = 0, column = 0, value = 1;
  for (let low = 0, high = n - 1; low <= high; high -= 1) {
    for (; column < high; matrix[row][column] = value, column += 1, value += 1);
    for (; row < high; matrix[row][column] = value, row += 1, value += 1);
    for (; column > low; matrix[row][column] = value, column -= 1, value += 1);
    for (low += 1; row > low; matrix[row][column] = value, row -= 1, value += 1);
  }
  matrix[row][column] = value;
  return matrix;
}

console.log(spiralMatrix(3)); // [[1, 2, 3], [8, 9, 4], [7, 6, 5]]
console.log(spiralMatrix(4)); // [[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]}
Enter fullscreen mode Exit fullscreen mode

Though the arrays are going to be the holey rather than the packed kind.