Заполнить матрицу целыми числами по спирали JS

202
02 декабря 2021, 00:10

Здравствуйте! Написала скрипт, который, по идее, должен генерировать матрицу размером 3х3 по спирали, начиная с левой стороны. Все бы ничего, но у меня выскакивает ошибка, что переменная number не определена или равна нулю. Посмотрите, пожалуйста, мой код. Может я где-то ошиблась. Сама уже не знаю в чем дело. Буду благодарна очень, если найдете еще какие-либо косяки.

Переписала код, как и советовали. Формируется матрица 3х3, но заполняется неправильно(

var numbers = [1,2,3,4,5,6,7,8,9];
var dimension = 3;
var matrix = [];
for(var d = 0; d<dimension; d++){
    matrix[d] = [];
}
    makeMatrix(numbers, dimension, matrix);

function makeMatrix(numbers, dimension, matrix){
    for(var n = 0; n < numbers.length; n++){
  var i = 0; 
  var j = 0;
    var number = numbers[n];
    moveDown(i, j, matrix, number);
  }
  console.log(matrix);
}
function moveDown(i, j, matrix, number){
    for(j; j<dimension; j++){
    matrix[i][j]=number;
    if(matrix[i][j+1]!="" && matrix[i+1][j]==""){
        i = i+1;
      moveRight(i, j, matrix, number);
        }
    }
  }
  function moveRight(i, j, matrix, number){
    for(i; i<dimension; i++){
        matrix[i][j]=number;
      if(matrix[i+1][j]!="" && matrix[i][j-1]==""){
        j = j-1;
        moveUp(i, j, matrix, number);
      }
    }
  }
  function moveUp(i, j, matrix, number){
    for(j; j>=0; j++){
        matrix[i][j]=number;
      if(matrix[i][j-1]!="" && matrix[i-1][j]==""){
        i = i-1;
        moveLeft(i, j, matrix, number);
      }
    }
  }
  function moveLeft(i, j, matrix, number){
    for(i; i>=0; i++){
        matrix[i][j]=number;
      if(matrix[i-1][j]!="" && matrix[i][j+1]==""){
        dimension = dimension/2;
        makeMatrix(numbers, dimension);
      }
    }
  }

В итоге должна появится матрица такого вида:

Answer 1

Думаю как-то так. Можно и ужать, но так нагляднее.

matrixView(spiralMatrix(2)); 
matrixView(spiralMatrix(3)); 
matrixView(spiralMatrix(4)); 
matrixView(spiralMatrix(5)); 
 
function spiralMatrix( dimension ) { 
  let matrix = [], 
    x = y = 0, 
    steps = dimension - 1; // Кол-во шагов в ту или иную сторону 
     
  for(let i = 0; i < dimension; i++) matrix[i] = []; // Создаем матрицу 
 
  for(let i = 1; i <= Math.pow(dimension, 2); i++) { 
    matrix[y][x] = i; // Задаем значение 
 
    // Меняем кол-во шагов 
    if(x === steps && y === dimension - steps - 1) steps--; 
 
    // Движение "вниз" 
    if((y >= x && y < steps) || (x - 1 === y && x === dimension - steps - 1)) y++; 
    // Движение "вверх" 
    else if(y <= x && y >= dimension - steps) y--; 
    // Движение "вправо" 
    else if(x <= y && x < steps) x++; 
    // Движение "влево" 
    else if(x >= y && x >= dimension - steps) x--; 
  } 
   
  return matrix; 
} 
 
function matrixView( matrix ) { 
  let rows = ''; 
 
  for(let i = 0; i < matrix.length; i++) { 
    let cells = ''; 
 
    for(let j = 0; j < matrix[i].length; j++) { 
      cells += '<div class="block_cell">' + matrix[i][j] + '</div>'; 
    } 
 
    rows += '<div class="block_row">' + cells + '</div>'; 
  } 
 
  document.querySelector('body').insertAdjacentHTML('beforeend', '<div class="block">' + rows + '</div>'); 
}
body { 
  background-color: #dddddd; 
} 
 
.block { 
  margin-bottom: 20px; 
} 
 
.block_row { 
  font-size: 0; 
} 
 
.block_cell { 
  display: inline-block; 
  vertical-align: top; 
  width: 40px; 
  height: 40px; 
  margin: 3px; 
  border-radius: 4px; 
  box-shadow: 1px 1px 3px #a0a0a0; 
  background-color: #fff; 
  font-family: Arial, sans-serif; 
  font-size: 14px; 
  text-align: center; 
  line-height: 40px; 
}

Answer 2

Решение через рекурсию

var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25];
var x = 0,
    y = 0;
var direction = 'right';
var numberPosition = 0;
var innerDimension;
var dimension = 5;
var oldPosition;

var matrix = createMatrix(5, 5);
fillMatrix();
// Результат
console.log(matrix);
function fillMatrix(){
    if (!numbers.length) return;
    var num = numbers.shift();
    matrix[x][y] = num;
    ++numberPosition;
    // Матрица заполнена
    if (innerDimension === 0) return;
    // Последнее значение поля матрицы
    if (innerDimension === 1) {
        getNextDirection();
        setNextPosition();
        innerDimension = 0;
        fillMatrix();
        return;
    }
    // Первый поворот
    if (numberPosition === innerDimension || numberPosition === dimension) {
        getNextDirection();
        setNextPosition();
        oldPosition = numberPosition;
        innerDimension = dimension - 1;
        fillMatrix();
        return;
    }
    // Поворот направления
    if (numberPosition === oldPosition + innerDimension || numberPosition === oldPosition + (innerDimension * 2)) {
        if (numberPosition === oldPosition + (innerDimension * 2)) {
            innerDimension = innerDimension - 1;
            oldPosition = numberPosition;
        }
        getNextDirection();
        setNextPosition();
        fillMatrix();
        return;
    }

    setNextPosition();
    fillMatrix();
}
function setNextPosition() {
    if (direction == 'right') {
        y = y + 1;
    }
    if (direction == 'down') {
        x = x + 1;
    }
    if (direction == 'left') {
        y = y - 1;
    }
    if (direction == 'top') {
        x = x - 1;
    }
}
function getNextDirection() {
    if (direction === 'right') {
        direction = 'down';
        return;
    }
    if (direction === 'down'){
        direction = 'left';
        return;
    }
    if (direction === 'left') {
        direction =  'top';
        return;
    }
    if (direction === 'top') {
        direction = 'right';
    }
}
function createMatrix(x, y) {
    var matrix = [];
    for (var i = 0; i < x; i++) {
        matrix[i] = Array(y);
    }
    return matrix;
}
Answer 3

Ответ на C, можете переделать, да и может кому пригодится. Код не оптимальный.

#include <stdio.h>
#define M 6
#define N 8
int matrix[M][N];
void fill_spiral()
{
    int
        i, // столбец
        j, // строка
        dj, di, // направление движения
        v, // значение
        tmp_di; // временная переменная
    // заполняем нулями
    for (j = 0; j < M; j++)
        for (i = 0; i < N; i++)
            matrix[j][i] = 0;
    // заполняем по спирали
    for (v = 1, i = 0, j = -1, dj = 1, di = 0; v <= M*N; v++) {
        // делаем шаг
        i += di; j += dj;
        // если въехали в уже заполненное или выехали за пределы матрицы
        if (i < 0 || j < 0 || i == N || j == M || matrix[j][i] != 0) {
            // отменяем шаг
            i -= di; j -= dj;
            // возвращаем значение
            v--;
            // применяем матрицу поворота на PI/2 для направления
            tmp_di = di;
            di = dj;
            dj = -tmp_di;
            continue;
        }
        // заполняем матрицу
        matrix[j][i] = v;
    }
}
int main()
{
    int i, j;
    fill_spiral();
    for (j = 0; j < M; j++)
    {
        printf("%3d", matrix[j][0]);
        for (i = 1; i < N; i++)
            printf(", %3d", matrix[j][i]);
        puts(";");
    }
    return 0;
}

Результат:

  1,  24,  23,  22,  21,  20,  19,  18;
  2,  25,  40,  39,  38,  37,  36,  17;
  3,  26,  41,  48,  47,  46,  35,  16;
  4,  27,  42,  43,  44,  45,  34,  15;
  5,  28,  29,  30,  31,  32,  33,  14;
  6,   7,   8,   9,  10,  11,  12,  13;

Верхний код не оптимальный, а ниже более оптимальный, который не опирается на уже занесенные в матрицу данные, таким образом может использоваться для заполнения матрицы произвольными значениями, включая нули (правда тут у меня указатели, не знаю как на JS повторить; есть ли в JS ссылки). И уже без комментариев. Кто работал, тот поймет)

void fill_spiral()
{
    int i = 0, j = -1, dj = 1, di = 0, v = 1, tmp_di, stepsN = N,
        stepsM = M, *steps = &stepsM, k;
    while (*steps > 0) {
        for (k = 0; k < *steps; k++) {
            i += di; j += dj;
            matrix[j][i] = v++;
        }
        steps = (dj == 0 ? &stepsM : &stepsN); (*steps)--;
        tmp_di = di; di = dj; dj = -tmp_di;
    }
}
READ ALSO
Калькулятор на чистом JS

Калькулятор на чистом JS

Я недавно начал изучать JS (чистый) и решил создать калькуляторНесколько сделать удалось, но с одним не могу разобраться вот уже 10-ый день

78
Почему телеграм не отображает превью конкретно моей ссылки?

Почему телеграм не отображает превью конкретно моей ссылки?

К примеру, когда я делюсь ссылкой на другие сайты, телеграм подхватывает и делает превью, однако в случае с моим веб-ресурсом такое не происходит:

309
Как работать со встраиваемой БД?

Как работать со встраиваемой БД?

Я использую Intellij IDEA для сборки проекта(javafx + hibernate), но после создания jar файла база не может быть найдена (чисто теоретически я могу создать...

146