Game of Life: Next Generation
Problem
The matrix has live cells (1) and dead cells (0). A cell has up to 8 neighbours (also diagonal). A live cell with 2 or 3 live neighbours stays alive, otherwise it dies. A dead cell with exactly 3 live neighbours becomes alive. All cells change at the same time. Print the next generation. Cells outside the matrix are dead.
Constraints
- 1 <= r, c <= 100
- cells are 0 or 1
Examples
Input
3 3 0 1 0 0 1 0 0 1 0
Output
0 0 0 1 1 1 0 0 0
Solutions
If you change cells while you scan, later cells see the new values and the result is wrong. A second matrix (or encoding old and new states in one number) keeps the generation change simultaneous.
/*
* Problem : Process a matrix.
* Input : r and c, then r rows of c integers.
* Output : The next generation.
* Approach: Count neighbours.
* Time : O(r * c)
* Space : O(r * c)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static String[] solve(int[][] m) {
int rows = m.length;
int cols = m[0].length;
// Step 1: Write the new generation in a second matrix. All cells must be computed from the OLD generation.
int[][] next = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
// Step 2: Count the live neighbours. The cell itself is skipped. Cells outside the matrix count as dead.
int neighbours = 0;
for (int x = i - 1; x <= i + 1; x++) {
for (int y = j - 1; y <= j + 1; y++) {
if ((x != i || y != j) && x >= 0 && x < rows && y >= 0 && y < cols) {
neighbours += m[x][y];
}
}
}
// Step 3: Apply the rules.
if (m[i][j] == 1) {
next[i][j] = neighbours == 2 || neighbours == 3 ? 1 : 0;
} else {
next[i][j] = neighbours == 3 ? 1 : 0;
}
}
}
String[] output = new String[rows];
for (int i = 0; i < rows; i++) {
StringBuilder row = new StringBuilder();
for (int j = 0; j < cols; j++) {
row.append(j == 0 ? "" : " ").append(next[i][j]);
}
output[i] = row.toString();
}
return output;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int rows = scanner.nextInt();
int cols = scanner.nextInt();
int[][] m = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m[i][j] = scanner.nextInt();
}
}
System.out.println(String.join("\n", solve(m)));
}
}
Hints (1)
- Why do we need a second matrix?