package com.freetymekiyan.algorithms.level.medium; /** * According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellular automaton devised * by the British mathematician John Horton Conway in 1970." * <p> * Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its * eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia * article): * <p> * Any live cell with fewer than two live neighbors dies, as if caused by under-population. * Any live cell with two or three live neighbors lives on to the next generation. * Any live cell with more than three live neighbors dies, as if by over-population.. * Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction. * Write a function to compute the next state (after one update) of the board given its current state. * <p> * Follow up: * Could you solve it in-place? Remember that the board needs to be updated at the same time: You cannot update some * cells first and then use their updated values to update other cells. * In this question, we represent the board using a 2D array. In principle, the board is infinite, which would cause * problems when the active area encroaches the border of the array. How would you address these problems? * <p> * Tags: Array * Similar Problems: (M) Set Matrix Zeroes */ public class GameOfLife { /** * Bit-manipulation. * Use 2 bit for each cell to represent both current and next states. * 00, 01, 10, 11. * Then scan the matrix again to generate result. */ public void gameOfLife(int[][] board) { 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 = -board[i][j]; // If the current cell is live, it will be deducted from result for (int k = Math.max(i - 1, 0); k < Math.min(i + 2, m); k++) { for (int l = Math.max(j - 1, 0); l < Math.min(j + 2, n); l++) { lives += board[k][l] & 1; } } if ((lives | board[i][j]) == 3) { // lives = 2 or 3, board[i][j] = 1, or lives = 3, board[i][j] = 0 board[i][j] |= 2; } } } for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { board[i][j] >>= 1; } } } }