Conway's Cellular Automaton Step
Problem
Apply one Game-of-Life step to a board: a live cell with two or three live neighbours stays alive; a dead cell with exactly three live neighbours becomes alive; everything else dies or stays dead. To do it in place, encode transitions in two extra bits — keep the current state in bit 0 and the next state in bit 1, then right-shift every cell at the end. Counting neighbours uses the eight surrounding offsets.
Input
[[0,1,0],[0,0,1],[1,1,1],[0,0,0]]Output
[[0,0,0],[1,0,1],[0,1,1],[0,1,0]]Classic blinker → glider transition.
def game_of_life(board):
m, n = len(board), len(board[0])
dirs = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]
for r in range(m):
for c in range(n):
live = 0
for dr, dc in dirs:
nr, nc = r + dr, c + dc
if 0 <= nr < m and 0 <= nc < n and board[nr][nc] & 1:
live += 1
cur = board[r][c] & 1
nxt = 1 if (cur == 1 and live in (2, 3)) or (cur == 0 and live == 3) else 0
board[r][c] |= nxt << 1
for r in range(m):
for c in range(n):
board[r][c] >>= 1
function gameOfLife(board) {
const m = board.length, n = board[0].length;
const dirs = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]];
for (let r = 0; r < m; r++) {
for (let c = 0; c < n; c++) {
let live = 0;
for (const [dr, dc] of dirs) {
const nr = r + dr, nc = c + dc;
if (nr >= 0 && nr < m && nc >= 0 && nc < n && (board[nr][nc] & 1) === 1) live++;
}
const cur = board[r][c] & 1;
const next = (cur === 1 && (live === 2 || live === 3)) || (cur === 0 && live === 3) ? 1 : 0;
board[r][c] |= (next << 1);
}
}
for (let r = 0; r < m; r++) {
for (let c = 0; c < n; c++) board[r][c] >>= 1;
}
}
class Solution {
public void gameOfLife(int[][] board) {
int m = board.length, n = board[0].length;
int[][] dirs = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
for (int r = 0; r < m; r++) {
for (int c = 0; c < n; c++) {
int live = 0;
for (int[] d : dirs) {
int nr = r + d[0], nc = c + d[1];
if (nr >= 0 && nr < m && nc >= 0 && nc < n && (board[nr][nc] & 1) == 1) live++;
}
int cur = board[r][c] & 1;
int next = ((cur == 1 && (live == 2 || live == 3)) || (cur == 0 && live == 3)) ? 1 : 0;
board[r][c] |= (next << 1);
}
}
for (int r = 0; r < m; r++)
for (int c = 0; c < n; c++) board[r][c] >>= 1;
}
}
void gameOfLife(vector<vector<int>>& board) {
int m = board.size(), n = board[0].size();
int dirs[8][2] = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
for (int r = 0; r < m; ++r) {
for (int c = 0; c < n; ++c) {
int live = 0;
for (auto& d : dirs) {
int nr = r + d[0], nc = c + d[1];
if (nr >= 0 && nr < m && nc >= 0 && nc < n && (board[nr][nc] & 1)) live++;
}
int cur = board[r][c] & 1;
int nx = ((cur == 1 && (live == 2 || live == 3)) || (cur == 0 && live == 3)) ? 1 : 0;
board[r][c] |= (nx << 1);
}
}
for (int r = 0; r < m; ++r)
for (int c = 0; c < n; ++c) board[r][c] >>= 1;
}