/*
[2nd bit, 1st bit] = [next state, current state]
- 00 dead (next) <- dead (current)
- 01 dead (next) <- live (current)
- 10 live (next) <- dead (current)
- 11 live (next) <- live (current)
*/
public class Solution {
private int liveNeighbors(int[][] board, int m, int n, int x, int y) {
int res = 0;
for (int i = Math.max(x - 1, 0); i <= Math.min(m - 1, x + 1); i++) {
for (int j = Math.max(y - 1, 0); j <= Math.min(n - 1, y + 1); j++) {
res += board[i][j] & 1;
}
}
res -= board[x][y] & 1;
return res;
}
public void gameOfLife(int[][] board) {
if (board == null || board.length < 1 || board[0].length < 1) return;
int m = board.length;
int n = board[0].length;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int lives = liveNeighbors(board, m, n, i, j);
if (board[i][j] == 1 && lives >= 2 && lives <= 3) { // 2nd Rule
board[i][j] = 3;
}
if (board[i][j] == 0 && lives == 3) { // 4th Rule
board[i][j] = 2;
}
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
board[i][j] >>= 1;
}
}
}
}