function q2(input, renderSize = 9) {
const height = input.length;
const width = input[0].length;
let state = [];
let state2 = [];
for (const row of input) {
state.push(...row);
state2.push(...row);
}
let changedState = true;
const { max, min } = Math;
const FLOOR = 0;
const EMPTY = 1;
const OCCUPIED = 10;
const CROWDED = OCCUPIED * 5;
const maxTurns = 100;
let turns = 0;
let results = [];
const directions = [
[-1, -1],
[-1, 0],
[-1, 1],
[0, -1],
[0, 1],
[1, -1],
[1, 0],
[1, 1]
];
const inside = (x, y) => {
return x >= 0 && x < width && y >= 0 && y < height;
};
do {
changedState = false;
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
let seat = state[x + y * width];
if (seat === FLOOR) continue;
let adjacent = 0;
for (const [dx, dy] of directions) {
let i = dx,
j = dy;
let neighbor = FLOOR;
while (inside(x + i, y + j)) {
neighbor = state[x + i + (y + j) * width];
if (neighbor !== FLOOR) break;
i += dx;
j += dy;
}
adjacent += neighbor;
}
if (adjacent >= CROWDED && seat === OCCUPIED) {
changedState = true;
state2[x + y * width] = EMPTY;
} else if (adjacent < OCCUPIED && seat === EMPTY) {
changedState = true;
state2[x + y * width] = OCCUPIED;
}
}
}
for (let i = 0; i < state.length; i++) {
state[i] = state2[i];
}
results.push(makeTiles(state, width, renderSize));
} while (changedState && ++turns < maxTurns);
let totalOccupied = 0;
for (const tile of state) {
totalOccupied += tile === OCCUPIED;
}
return { results, totalOccupied, turns, changedState, state };
}