как проверить пустое значение в многомерном массиве в этом поле - PullRequest
0 голосов
/ 07 марта 2019

привет, я хочу знать алгоритм, чтобы найти пустое значение вокруг поля 3x3

пример многомерного массива, подобного этому

[
    [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "],
    [" ", " ", "#", " ", "#", " ", " ", " ", " ", " "],
    [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"],
    [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"],
    [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  ]

Я просто хочу получить поле только 3х3, поэтому пустое значение внутри этого поля я могу заполнить всем, что захочу, как решить / проверить для этого случая? в результате получаем пустое значение INDEX

я пытаюсь с этим:

for (let i = 0; i < array.length; i++) {
    for (let j = 0; j < array[i].length; j++) {
      if(array[i]){
        if(array[i][j] == '#' &&
           array[i+1][j] == '#' && 
           array[i+2][j] == '#' &&
           array[i][j+1] == '#' && 
           array[i][j+2] == '#' &&
           array[i+2][j+2]

         ){
           console.log(i);
         }
      }

    }
  }

Ответы [ 5 ]

2 голосов
/ 07 марта 2019

1) Ваш ящик 3х3 = 9 ячеек для проверки.Вы проверяете только шесть из них.

2) Вы проверяете index + 2, начиная с верхнего левого угла вправо и вниз, это означает, что вы должны прекратить зацикливание на length - 2.

3) В основном вам необходимо обратиться к каждой ячейке в этой области 3х3.

Вот как вы это делаете :

for (let i = 0; i < array.length - 2; i++) {
    for (let j = 0; j < array[i].length - 2; j++) {
        if (
            // first row
            array[i][j] == '#'
            && array[i][j + 1] == '#'
            && array[i][j + 2] == '#'

            // second row
            && array[i + 1][j] == '#'
            && array[i + 1][j + 1] == ' '
            && array[i + 1][j + 2] == '#'

            // third row
            && array[i + 2][j] == '#'
            && array[i + 2][j + 1] == '#'
            && array[i + 2][j + 2] == '#'
         ) {
            console.log('box upper-left corner is: ' + i + ' x ' + j + '<br />');
         }

    }
}

Если вы ищете адресячейка "emtpy" внутри коробки, то вы ищете i + 1 и j + 1.

0 голосов
/ 07 марта 2019

Вот объектно-ориентированный подход:

class Cell {
  constructor(coordinates, content) {
    this.coordinates = coordinates;
    this.content = content;
  }

  get allNeighbours() {
    return Cell
      .neighbourDirections
      .map(direction => this[direction]);
  }

  get neighbours() { // unused
    return this.allNeighbours
      .filter(neighbour => neighbour);
  }

  get isBoxCentre() {
    return this.content === ' ' &&
      this.allNeighbours
        .every(neighbour => neighbour && neighbour.content === '#');
  }
}

Cell.relativeNeighbourDirections = {
  north: [0, 1],  northEast: [1, 1], 
  east:  [1, 0],  southEast: [1, -1],
  south: [0, -1], southWest: [-1, -1], 
  west:  [-1, 0], northWest: [-1, 1]
};

Cell.neighbourDirections = Object.keys(Cell.relativeNeighbourDirections);


class Grid {
  constructor(gridArray) {
    this.cells = [];

    // instantiate cells
    this.gridArray = gridArray.map((row, x) => {
      return row.map((content, y) => {
        let cell = new Cell([x, y], content);
        this.cells.push(cell);
        return cell;
      });
    });
    
    this._assignNeighbours();
  }

  // returns an array with the coordinates of all box centres
  get boxCoordinates() {
    return this.cells
      .filter(cell => cell.isBoxCentre)
      .map(cell => cell.coordinates);
  }

  _assignNeighbours() {
    this.gridArray.forEach((row, x) => {
      row.forEach((cell, y) => {
        Cell.neighbourDirections.forEach(direction => {
          let [relX, relY] = Cell.relativeNeighbourDirections[direction];

          let neighbourX = x + relX,
              neighbourY = y + relY;

          // x and y must be in bounds
          if (
            neighbourX < 0 ||
            neighbourX >= this.gridArray.length ||
            neighbourY < 0 ||
            neighbourY >= row.length
          ) return;

          cell[direction] = this.gridArray[neighbourX][neighbourY];
        });
      });
    });
  }
}


let grid = new Grid([
    [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "],
    [" ", " ", "#", " ", "#", " ", " ", " ", " ", " "],
    [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"],
    [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"],
    [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
]);

console.log(grid.boxCoordinates);

Для получения дополнительной информации о классах JavaScript, проверьте: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

0 голосов
/ 07 марта 2019

Я начал с создания двух положительных тестовых случаев для нашей функции check -

const puzzle1 =
  [ [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "]
  , [" ", " ", "#", " ", "#", " ", " ", " ", " ", " "]
  , [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
  , [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  ]

const puzzle2 =
  [ [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
  , [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
  , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
  , [" ", " ", " ", " ", "#", " ", "#", " ", " ", " "]
  , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  ]

console.log(check(puzzle1))
// expected: [ 0, 2 ]

console.log(check(puzzle2))
// expected: [ 3, 4 ]

И отрицательный случай -

const puzzle3 =
  [ [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
  , [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
  , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
  , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
  , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  ]

console.log(check(puzzle3))
// expected: false

Сначала я реализовал cross и blank для более легкой обработки подзадач -

const cross = x =>
  x === "#"

const blank = x =>
  x === " "

Теперь мы реализуем check -

const check = 
  ( [ [ a, b, c, ...r0 ] = []
    , [ d, e, f, ...r1 ] = []
    , [ g, h, i, ...r2 ] = []
    , ...rest
    ]
  , row = 0
  , col = 0
  ) =>

  // bottom-right is out of bounds
  i === undefined
    ? false

  // perimeter is cross and center is blank
  // solution found: return the row and col
  : [ a, b, c, d, f, g, h, i ] .every (cross) && blank (e)
    ? [ row, col ]

  // otherwise check the next column
  : check
      ( [ [ b, c, ...r0 ]
        , [ e, f, ...r1 ]
        , [ h, i, ...r2 ]
        , ...rest .map (([ _, ...row ]) => row)
        ]
      , row
      , col + 1
      )
    || // or check the next row
    check
      ( [ [ d, e, f, ...r1 ]
        , [ g, h, i, ...r2 ]
        , ...rest
        ]
      , row + 1
      , col
      )

Мне нравится это решение, потому что мы можем визуально увидеть, что происходит в чеке -

// (a b c f i h g d) makes a "donut" shape
// (e) is the donut hole
[ [ a, b, c, ...r0 ] = []
, [ d, e, f, ...r1 ] = []
, [ g, h, i, ...r2 ] = []
, ...rest
]

// how am I supposed to visualize this?
arr[row][col] == "#"
arr[row+1][col] == "#"
arr[row+2][col] == "#"
arr[row][col+1] == "#"
arr[row+1][col+1] == " "
arr[row+2][col+1] == "#"
arr[row][col+2] == "#"
arr[row+1][col+2] == "#"
arr[row+2][col+2] == "#"

Использование вложенных циклов for заставляет нас задуматься о проблеме, используя индексы и выполняя поиск вручную, например arr[row+1][col+2]. Мышление на этом уровне детализации утомляет мозг и порождает ошибочные программы. Напротив, использование глубокой деструктуризации и рекурсии позволяет нашей программе отражать форму своих данных и освобождает нас от сложности.

Разверните программу ниже, чтобы проверить результаты в вашем собственном браузере -

const cross = x =>
  x === "#"
  
const blank = x =>
  x === " "

const check = 
  ( [ [ a, b, c, ...r0 ] = []
    , [ d, e, f, ...r1 ] = []
    , [ g, h, i, ...r2 ] = []
    , ...rest
    ]
  , row = 0
  , col = 0
  ) =>
  i === undefined
    ? false
  : [ a, b, c, d, f, g, h, i ] .every (cross) && blank(e)
    ? [ row, col ]
  : check
      ( [ [ b, c, ...r0 ]
        , [ e, f, ...r1 ]
        , [ h, i, ...r2 ]
        , ...rest .map (([ _, ...row ]) => row)
        ]
      , row
      , col + 1
      )
    ||
    check
      ( [ [ d, e, f, ...r1 ]
        , [ g, h, i, ...r2 ]
        , ...rest
        ]
      , row + 1
      , col
      )

const puzzle1 =
  [ [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "]
  , [" ", " ", "#", " ", "#", " ", " ", " ", " ", " "]
  , [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
  , [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  ]

const puzzle2 =
  [ [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
  , [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
  , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
  , [" ", " ", " ", " ", "#", " ", "#", " ", " ", " "]
  , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  ]

const puzzle3 =
  [ [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
  , [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
  , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
  , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
  , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  ]

console.log(check(puzzle1))
// [ 0, 2 ]

console.log(check(puzzle2))
// [ 3, 4 ]

console.log(check(puzzle3))
// false
0 голосов
/ 07 марта 2019

Вы были на правильном пути, вот ваша версия с небольшими изменениями и дополнениями:

array = [
  [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "],
  [" ", " ", "#", "find me", "#", " ", " ", " ", " ", " "],
  [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "],
  [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
  [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
  [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"],
  [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "],
  [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"],
  [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
]

for (let i = 0; i < array.length-2; i++) {
  for (let j = 0; j < array[i].length-2; j++) {
    if(array[i][j] == '#' &&
    array[i+1][j] == '#' && 
    array[i+2][j] == '#' &&
    array[i][j+1] == '#' && 
    array[i][j+2] == '#' &&
    array[i+1][j+2] == '#' &&
    array[i+2][j+1] == '#' &&
    array[i+2][j+2] == '#'){
      console.log(array[i+1][j+1]);
    }
  }
}
0 голосов
/ 07 марта 2019

Вы можете искать первые ### в каждой строке, так как это верхняя граница.Затем, как только вы найдете его, убедитесь, что остальная часть коробки существует.Если это так, вы нашли первую коробку 3х3:

var arr = [
    [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "],
    [" ", " ", "#", " ", "#", " ", " ", " ", " ", " "],
    [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"],
    [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"],
    [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  ];
  
for (let i = 0; i < arr.length; i++) {

  //convert row to string
  let row = arr[i].join("");
  
  //search for top border
  if (row.indexOf("###") != -1) {
    
    let ind = row.indexOf("###");

    //verify box
    if (arr[i+1][ind] == "#" && arr[i+1][ind+2] == "#" && arr[i+2].join("").substr(ind,3) == "###") {
      console.log("Found at: " + i + ", " + ind);
      break;
    }
  }
}
...