Поскольку сейчас мы не на собеседовании, я решил сохранить код не компактным, чтобы его было легче понять.Вы можете сократить его, если хотите.Мне нравятся такие проблемы, поэтому я не торопился с этим.
Также я обновил визуальную сетку.Теперь вы можете видеть состояние сетки при ее изменении.
var lamps = [
[1,6],
[5,6],
[7,3],
[3,2]
];
var queries = [
[4,4],
[6,6],
[8,1],
[3,2],
[2,3]
];
/* ==================== VISUAL GRID ==================== */
function arrayFlatten(array) {
var result = [];
array.forEach(function (item) {
if (item instanceof Array) {
result = result.concat(arrayFlatten(item));
} else {
result.push(item);
}
});
return result;
}
function createGrid(lamps, queries) {
var grid = document.createElement("table");
grid.classList.add("grid");
var gridSize = Math.max.apply(null, arrayFlatten([lamps, queries])) + 1;
document.body.appendChild(grid);
// create cells
for (var i = 0; i < gridSize; i++) {
var row = document.createElement("tr");
for (var j = 0; j < gridSize; j++) {
var cell = document.createElement("td");
row.appendChild(cell);
}
grid.appendChild(row);
}
// add lamps
lamps.forEach(lamp => grid.rows[lamp[1]].cells[lamp[0]].classList.add("lamp"));
var illuminatedRows = Array.from(new Set(lamps.map(([lampX, lampY]) => lampY)));
var illuminatedCols = Array.from(new Set(lamps.map(([lampX, lampY]) => lampX)));
illuminatedRows.sort();
illuminatedCols.sort();
// add lights
// horizontal
for (var i = 0; i < grid.rows.length; i++) {
if (illuminatedRows.includes(i)) {
Array.from(grid.rows[i].cells).forEach(cell => cell.classList.add("horizontal-light"));
}
}
// vertical
for (var i = 0; i < grid.rows.length; i++) {
for (var j = 0; j < grid.rows[i].cells.length; j++) {
if (illuminatedCols.includes(j)) {
grid.rows[i].cells[j].classList.add("vertical-light");
}
}
}
// diagonal
for (var i = 0; i < grid.rows.length; i++) {
for (var j = 0; j < grid.rows[i].cells.length; j++) {
var x = j;
var y = i;
lamps.forEach(function (lamp) {
if (isDiagonal(lamp[0], lamp[1], x, y)) {
grid.rows[i].cells[j].classList.add("diagonal-light");
}
});
}
}
}
createGrid(lamps, queries);
/* ==================== CALCULATION ==================== */
function isHorizontal(y1, y2) {
return y1 == y2;
}
function isVertical(x1, x2) {
return x1 == x2;
}
function isDiagonal(x1, y1, x2, y2) {
return Math.abs(x1 - x2) == Math.abs(y1 - y2);
}
function isIlluminated(queryX, queryY, lampX, lampY) {
return isHorizontal(queryY, lampY) || isVertical(queryX, lampX) || isDiagonal(queryX, queryY, lampX, lampY);
}
function isAdjacent(x1, y1, x2, y2) {
return Math.abs(x2 - x1) < 2 && Math.abs(y2 - y1) < 2
}
// check every lamp for each query
function checkLamps(lamps, queryX, queryY) {
// store checks for each lamp for a query
var checks = [];
// loop every lamp
for (var i = lamps.length - 1; i >= 0; i--) {
var lampX = lamps[i][0];
var lampY = lamps[i][1];
// check if the target cell is adjacent to the current lamp
if (isAdjacent(queryX, queryY, lampX, lampY)) {
console.log("Query (" + [queryX, queryY].join() + ") is adjacent to lamp (" + [lampX, lampY].join() + "). Removing this lamp.");
// lamp is adjacent; remove it
lamps.splice(i, 1);
// create a grid with the new state (for visual purposes)
createGrid(lamps, queries);
// skip this lamp
continue;
} else {
// storing the check for the current lamp
checks.push(isIlluminated(queryX, queryY, lampX, lampY));
}
}
// if all checks are false, it's dark
// if there's even a single true, that means the cell is illuminated by a lamp
if (checks.includes(true)) {
console.log("(" + [queryX, queryY].join() + ") is LIGHT");
} else {
console.log("(" + [queryX, queryY].join() + ") is DARK");
}
}
function checkLampIllumination(lamps, queries) {
// create a local copy of lamps because it'll (might) mutate
var lamps = lamps.slice();
// loop queries
queries.forEach(([queryX, queryY]) => checkLamps(lamps, queryX, queryY));
}
checkLampIllumination(lamps, queries);
.grid {
background-color: black;
border-collapse: collapse;
margin-right: 1em;
float: left;
}
.grid td {
width: 25px;
height: 25px;
border: 1px solid hsl(0, 0%, 50%);
}
.grid td.horizontal-light,
.grid td.vertical-light,
.grid td.diagonal-light {
background-color: hsla(0, 0%, 80%, .33);
}
.grid td.horizontal-light.vertical-light,
.grid td.horizontal-light.diagonal-light,
.grid td.vertical-light.diagonal-light {
background-color: hsla(0, 0%, 80%, .45);
}
.grid td.horizontal-light.vertical-light.diagonal-light {
background-color: hsla(0, 0%, 80%, .6);
}
.grid td.lamp {
background-color: hsl(0, 0%, 100%) !important;
}