I am currently tackling the challenge of game of life on LeetCode. You can find the problem here.
Here is the code I have been working on:
function isLive(board: number[][], row: number, column: number) {
let liveNeighbours = 0;
[row - 1, row, row + 1].forEach(r => {
if (r < 0 || r >= board.length) return;
[column - 1, column, column + 1].forEach(c => {
if (c === column && r === row) return;
if (c < 0 || c >= board[0].length) return;
if (board[r][c] === 1) liveNeighbours++
})
})
if (board[row][column] === 1 && (liveNeighbours === 3 || liveNeighbours === 2)) return true;
if (board[row][column] === 0 && liveNeighbours === 3) return true;
return false;
}
/**
Do not return anything, modify board in-place instead.
*/
function gameOfLife(board: number[][]): void {
let nextGen = Array(board.length).fill(Array(board[0].length).fill(0));
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[0].length; j++) {
console.log("isLive row ", i, " col ", j, isLive(board, i, j))
if (isLive(board, i, j)) nextGen[i][j] = 1
}
}
console.log("next gen", nextGen);
board = nextGen;
};
Upon running the code with this input:
[
[0,1,0],
[0,0,1],
[1,1,1],
[0,0,0]
]
The output matches the input which was unexpected. The expected output should be:
[
[0,0,0],
[1,0,1],
[0,1,1],
[0,1,0]
]
What's driving me crazy are the print logs. Even though each cell's liveliness is correctly determined, the final result doesn't match up. Here is a sample log:
isLive row 0 col 0 false
isLive row 0 col 1 false
isLive row 0 col 2 false
...
It seems that there might be an issue with how values are being assigned to arrays. I also attempted modifying the function to first return the count of neighbors before applying conditions, but encountered similar issues.
I've made some changes to my code, focusing on counting neighbors separately:
function countNeighbors(board: number[][], row:number, column:number){
let liveNeighbors = 0;
[row-1, row, row+1].forEach(r=>{
if(r<0 || r>= board.length) return;
[column-1, column, column+1].forEach(c=>{
if(c === column && r=== row) return;
if(c<0 || c>= board[0].length) return;
if(board[r][c]===1) liveNeighbors++
})
})
return liveNeighbors;
}
function gameOfLife(board: number[][]): void {
let neighbors = Array(board.length).fill(Array(board[0].length).fill(0));
for (let i = 0; i<board.length; i++){
for (let j = 0; j<board[0].length; j++){
let numberOfNeighbors = countNeighbors(board,i,j);
console.log(i, j, numberOfNeighbors)
neighbors[i][j] = numberOfNeighbors
}
console.log("neighbors", neighbors)
}
};
However, the log reveals duplicate rows for all iterations of i
, leading to incorrect results. It appears to be related to how the new array is initialized. Creating the array differently yields the desired outcome.
As much as pushing empty arrays during each iteration would work, it lacks elegance compared to the initial approach. I'm curious about what causes this behavior and if there's a better way to create the array without encountering this duplication problem.