Проблемы с вашим текущим кодом:
(1) Вы проверяете только отдельные строки и столбцы, когда вам нужно проверять их оба (например, с [[2, 2], [2, 5]]
, когда в начальной позиции[0][0]
, вам нужно посмотреть как [0][1]
(и его соседей, если они совпадают), так и [1][0]
(и его соседей, если они совпадают).
(2) Вы на самом деле непроверяя смежность в данный момент, вы просто подсчитываете общее количество совпадающих элементов в конкретной строке или столбце.
Перебор всех указателей массива. Если индекс уже проверен, вернитесь раньшеРекурсивно ищите соседей по этому индексу, и, если найдено как минимум 3 совпадающих, установите их всех равными 1. Поместите всех подходящих соседей в набор checked
, чтобы избежать их повторной проверки (даже если их было меньше 2 смежных).всего найдено совпадений).
setAllAdjacentToOne([
[3, 4, 5, 6, 7],
[3, 4, 5, 6, 7],
[3, 4, 5, 5, 5],
[3, 5, 6, 7, 4]
]);
// all 9s stay, the rest get set to 1:
setAllAdjacentToOne([
[2, 2, 9, 7, 7],
[2, 9, 9, 9, 7],
[3, 4, 4, 5, 5],
[9, 4, 5, 5, 9]
]);
function setAllAdjacentToOne(input) {
const output = input.map(subarr => subarr.slice());
const checked = new Set();
const getKey = (x, y) => `${x}_${y}`;
const width = input[0].length;
const height = input.length;
const getAllAdjacent = (x, y, numToFind, matches = []) => {
if (x >= width || x < 0 || y >= height || y < 0) {
return matches;
}
const key = getKey(x, y);
if (!checked.has(key) && input[y][x] === numToFind) {
checked.add(key);
matches.push({ x, y });
getAllAdjacent(x + 1, y, numToFind, matches);
getAllAdjacent(x - 1, y, numToFind, matches);
getAllAdjacent(x, y + 1, numToFind, matches);
getAllAdjacent(x, y - 1, numToFind, matches);
}
return matches;
};
output.forEach((innerRowArr, y) => {
innerRowArr.forEach((num, x) => {
const allAdjacent = getAllAdjacent(x, y, num);
if (allAdjacent.length <= 2) {
return;
}
allAdjacent.forEach(({ x, y }) => {
output[y][x] = 1;
});
});
});
console.log(JSON.stringify(output));
}