Given a binary grid[ ][ ] of size N*M, with each cell containing either 0 or 1, where 1 represents an alive cell and the 0 represents a dead cell. The task is to generate the next generation of cells based on the following rules:
 Any live cell with fewer than two live neighbors dies due to underpopulation.
 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 due to overpopulation.
 Any dead cell with exactly three live neighbors becomes a live cell by reproduction.
Here, the neighbor of a cell includes its adjacent cells as well as diagonal ones, so for each cell, a total of 8 neighbors are there.
Examples:
Input: N = 5, M = 10
0000000000
0001100000
0000100000
0000000000
0000000000
Output:
0000000000
0001100000
0001100000
0000000000
0000000000
Explanation:
The cells at (1, 3), (1, 4) and (2, 4) are alive and have 2 neighbours,
So, according to Rule 2, they live on to the next generation.
The cell at (2, 3) is dead and has exactly 3 neighbours,
So, according to Rule 4, it becomes a live cell.Input: N = 4, M = 5
00000
01100
00010
00000
Output:
00000
00100
00100
00000
Explanation:
The cells at (1, 1) and (2, 3) have only 1 neighbor,
So, according to Rule 1, they die.
The cell at (1, 2) is alive and has 2 neighbors,
So, according to Rule 2, it lives on to the next generation.
The cell at (2, 2) is dead and has exactly 3 neighbors,
So, according to Rule 4, it becomes a live cell.
Naive Approach:
We have already discussed an approach to this problem in Program for Conway’s Game Of Life  Set 1. In this approach an extra grid future[ ][ ] of size N*M is created to store the next generation of cells.
Time complexity: O(N*M)
Auxiliary Space: O(N*M)
Efficient Approach:
A spaceoptimized approach is possible for this problem, which uses no extra space. For every alive cell, increment its value by 1 each time we encounter an alive neighbor for it. And, for every dead cell, decrement its value by 1 each time we encounter an alive neighbor for it. Now, if the value in a cell is smaller than 0, it means it is a dead cell and if the value is greater than 0, it is an alive cell, also the magnitude of value in a cell will represent the number of its alive neighbors. In this way, an extra grid will not be required and a spaceoptimized solution is obtained. Detailed steps of this approach are as follows:
For the present grid position, we will look at all the neighbors.
 Traverse the whole grid.
 If the value of the neighbor is >= 1(i.e. initial value of the neighbor was 1)

If, the current cell is >= 1, just increment current cell value by 1.
Now, grid [ i ][ j ] > 0 will imply that initial grid [ i ][ j ] == 1. 
Else, the current cell is <= 0, just decrement the current cell value by 1.
Now, grid [ i ][ j ] <= 0 will imply that initial grid [ i ][ j ] == 0.

If, the current cell is >= 1, just increment current cell value by 1.

Now, generate the required new generation grid using the modified grid.

If the current cell value is > 0, there are 3 possible cases:
 If the value is < 3 then change it to 0.
 Else if the value is <= 4 then change it to 1.
 Else change the value to 0.

Else, the current cell value is <= 0.
 If the value is 3 then change it to 1.
 Else change it to 0.

If the current cell value is > 0, there are 3 possible cases:
Below is the implementation of above approach:
// C++ implementation of // the above approach #include <bits/stdc++.h> using namespace std; class GameOfLife { public : // Function to display the grid void print(vector<vector< int > > grid); // Function to check if // index are not out of grid bool save(vector<vector< int > > grid, int row, int col); // Function to get New Generation void solve(vector<vector< int > >& grid); }; void GameOfLife::print( vector<vector< int > > grid) { int p = grid.size(), q = grid[0].size(); for ( int i = 0; i < p; i++) { for ( int j = 0; j < q; j++) { cout << grid[i][j]; } cout << endl; } } bool GameOfLife::save( vector<vector< int > > grid, int row, int col) { return (grid.size() > row && grid[0].size() > col && row >= 0 && col >= 0); } // Possible neighboring indexes int u[] = { 1, 1, 0, 1, 1, 0, 1, 1 }; int v[] = { 0, 0, 1, 1, 1, 1, 1, 1 }; void GameOfLife::solve( vector<vector< int > >& grid) { int p = grid.size(), q = grid[0].size(); for ( int i = 0; i < p; i++) { for ( int j = 0; j < q; j++) { // IF the initial value // of the grid(i, j) is 1 if (grid[i][j] > 0) { for ( int k = 0; k < 8; k++) { if (save(grid, i + u[k], j + v[k]) && grid[i + u[k]] [j + v[k]] > 0) { // If initial value > 0, // just increment it by 1 grid[i][j]++; } } } // IF the initial value // of the grid(i, j) is 0 else { for ( int k = 0; k < 8; k++) { if (save(grid, i + u[k], j + v[k]) && grid[i + u[k]] [j + v[k]] > 0) { // If initial value <= 0 // just decrement it by 1 grid[i][j]; } } } } } // Generating new Generation. // Now the magnitude of the grid // will represent number of neighbours for ( int i = 0; i < p; i++) { for ( int j = 0; j < q; j++) { // If initial value was 1. if (grid[i][j] > 0) { // Since Any live cell with // < 2 live neighbors dies if (grid[i][j] < 3) grid[i][j] = 0; // Since Any live cell with // 2 or 3 live neighbors live else if (grid[i][j] <= 4) grid[i][j] = 1; // Since Any live cell with // > 3 live neighbors dies else if (grid[i][j] > 4) grid[i][j] = 0; } else { // Since Any dead cell with // exactly 3 live neighbors // becomes a live cell if (grid[i][j] == 3) grid[i][j] = 1; else grid[i][j] = 0; } } } } // Driver code int main() { vector<vector< int > > grid = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; GameOfLife obj; // Function to generate // New Generation inplace obj.solve(grid); // Displaying the grid obj.print(grid); return 0; } 
0000000000 0001100000 0001100000 0000000000 0000000000
Time complexity: O(N*M)
Auxiliary Space: O(1)
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a studentfriendly price and become industry ready.
Recommended Posts:
 Program for Conway's Game Of Life
 Conway's Game Of Life (Python Implementation)
 Program for Markov matrix
 Java Program to Add two Matrices
 Python program to add two Matrices
 Program for Sudoku Generator
 Program to multiply two matrices
 Program for addition of two matrices
 Program for subtraction of matrices
 Program for Rank of Matrix
 Program for Identity Matrix
 Program to find the Sum of each Row and each Column of a Matrix
 Program to print Spiral Pattern
 Python program to multiply two matrices
 Program to concatenate two given Matrices of same size
 Program to reverse the rows in a 2d Array
 Program to reverse words in a given string in C++
 Program to check if two given matrices are identical
 Program to find transpose of a matrix
 Program to Print Matrix in Z form
If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.