let gameOfLife = function(board) {
if (!board) return [];
let LIVE = 1,
DEAD = 0,
ALIVE_TO_DEAD = 0b01, // [next state, current state]
ALIVE_TO_ALIVE = 0b11,
DEAD_TO_ALIVE = 0b10,
DEAD_TO_DEAD = 0b00,
maxRow = board.length - 1,
maxCol = board[0].length - 1;
function getAdjacentCount(row, col, valueToCompare) {
let sum = 0;
for (let i = Math.max(row - 1, 0); i <= Math.min(row + 1, maxRow); i++) {
for (let j = Math.max(col - 1, 0); j <= Math.min(col + 1, maxCol); j++) {
if (i === row && j === col) continue;
if (board[i][j] & 1 === valueToCompare) sum = sum + 1;
}
}
return sum;
}
function getNextValue(row, col) {
const val = board[row][col];
let liveNeighbors = getAdjacentCount(row, col, LIVE);
if (val === LIVE) {
// Any live cell with fewer than two live neighbors dies, as if caused by under-population.
// Any live cell with more than three live neighbors dies, as if by over-population..
if (liveNeighbors < 2 || liveNeighbors > 3) {
return ALIVE_TO_DEAD;
}
// Any live cell with two or three live neighbors lives on to the next generation.
return ALIVE_TO_ALIVE;
}
// cell is DEAD
else {
// Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.
if (liveNeighbors === 3) {
return DEAD_TO_ALIVE;
}
// no condition
return DEAD_TO_DEAD;
}
}
for (let row = 0; row <= maxRow; row++) {
for (let col = 0; col <= maxCol;col++) {
board[row][col] = getNextValue(row, col);
}
}
for (let row = 0; row <= maxRow; row++) {
for (let col = 0; col <= maxCol;col++) {
board[row][col] = board[row][col] >> 1;
}
}
};