What is causing the incorrect assignment of values to my array?

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.

Answer №1

In essence, the situation in function gameOfLife() is that when you do board = nextGen;, you are essentially just changing the reference of the variable board to point to the object nextGen, without actually altering the data stored in board. In simple terms, you are renaming board to be the same as nextGen, while keeping the original data unchanged.

The solution lies in copying the content from nextGen to board using methods instead of directly assigning it like board =. One way to achieve this is:

for (let i = 0; i < board.length; i++) {
    board[i] = nextGen[i];
}

Edit:

Considering that initially, the output for each cell appeared correct with nextGen, the issue seems peculiar. It may be worthwhile to check if all brackets and semicolons are correctly placed to ensure proper execution of all if statements, especially since there is a specific condition where setting nextGen to 1 should occur but might not always get triggered by the neighboring if statement.

If all else fails, perhaps consider adopting a different approach altogether that eliminates the need for a nextGen object entirely. Instead of creating a new board for the next generation, calculate the number of neighbors each tile has directly. Then, based on the neighbor count and current status, modify the board according to the rules, eliminating the need for data duplication:

let neighbors = Array(board.length).fill(Array(board[0].length).fill(0));

// ============================================================================================================
// Insert code here to determine the number of neighbors and update 'neighbors' accordingly
// ============================================================================================================

for (let i = 0; i < board.length; i++) {
    for (let j = 0; j < board[0].length; j++) {
        if (board[i][j] === 1) { 
            if (neighbors[i][j] < 2 || 3 < neighbors [i][j]) {
                board[i][j]--;
            }
        } else { 
            if (neighbors[i][j] === 3 {
                board[i][j]++;
            }
        }
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

AngularJS utilizes the observe directive to dynamically inherit scope through attribute expressions

Here is my simple code: .controller('Ctrl', ['$scope', '$timeout', function ($scope, $timeout) { $timeout(function () { $scope.x = 5; }, 2000); }]) .directive('ngHey', ['$parse', function ( ...

Ways to optimize memory usage and eliminate Vue reactivity

I've encountered an issue where Vue's observer and reactive components are using up a significant amount of memory during runtime. You can see an example of this in the Memory allocation on DevTools. Is there a way to detach observables and preve ...

Can you explain the concepts of 'theme' and 'classes'?

Currently, I am working on a web application using React. I have chosen to incorporate the latest version of Material-UI for designing the user interface. During this process, I came across the demo examples provided by Material-UI (like ) In each demo ...

Calculating the quantity of items throughout an array of lists using C#

I am just starting to learn C#. I have an array of lists that resembles the following: var baskets = [ [apples, oranges, peaches], [oranges, grapes, bananas], [oranges, grapes, apples] [bananas, strawberries, peaches] ] My goal is to transform this array ...

Is it feasible to save an array value in a database and utilize it with a WHERE clause in Laravel?

I am looking to store an array type in a column within a database and then retrieve it using a WHERE clause to compare the n_group_code_id with the array($gID) as shown in the following function. CREATE TABLE IF NOT EXISTS `tb_notification` ( `id` int(1 ...

React's router activeClassName feature fails to apply the active class to child routes

<ul className="right hide-on-med-and-down"> <li><IndexLink to="/" activeClassName="active">ABOUT</IndexLink></li> <li><Link to="blog" activeClassName="active">BLOG</Link></li> <li><Link t ...

What is the most efficient method for fetching data from the server at regular intervals of 30 minutes?

As I search for a way to automatically update my webpage with fresh data from the server, I am faced with uncertainty regarding the frequency of these updates. The intervals could range anywhere from every 10 minutes to an hour, which makes it challenging ...

Utilizing jQuery to enable a div to follow the touchmove or mousemove events while also automatically

I am looking to create a basic function in my jQuery script. I want the pages to slide horizontally in response to the movement of a finger or cursor on the screen. While there are many plugins available for this purpose, I prefer a simple, customized solu ...

Navigating the ins and outs of cout: a beginner's

Within this code, I am extracting values from an Array using the size of the matrix represented by n. The process begins with indices 1;1 (is it appropriate to use these indices?) and then proceeds to calculate the sine value based on the given formula in ...

The Vue pagination component is optimized to load a single page at a time

There seems to be an issue with my paginate component as it is only displaying the first page despite the total number of objects I want to show: https://i.sstatic.net/rEonp8Rk.png Pagination Component Code: <paginate v-if="searchResults.length & ...

The integration of Css and Js files into Laravel 5.6 seems to have been successful, however, they are

I have decided to integrate a template into my Laravel project. I have placed the template files in the public folder and followed the usual procedure of using the command below to load the files: <link href="{{ asset('admin-panel') }}/di ...

Creating generic output types in TypeScript based on the input types

In my React-Native project, I'm focusing on implementing autocomplete and type validation. One of the challenges I'm facing is configuring the types for the stylesheet library I am using. A customized stylesheet is structured like this: const s ...

Methods for maintaining accuracy when updating a user's follower count using Node.js with MongoDB

In my latest project, I am developing a social API system that allows users to follow and unfollow each other. The user model I currently have set up looks like this: sourceId: { type: Schema.Types.ObjectId, ref: "user", required: t ...

jQuery is notorious for incorporating front-end JavaScript libraries that are riddled with security flaws

After conducting an optimization analysis of my website using Google Lighthouse, I came across a "Best Practices" issue that raised concerns: Some third-party scripts may pose security vulnerabilities that can be easily exploited by attackers. You can ac ...

Calculate the sum of an array and then invoke a callback function from within another function

I'm currently facing a challenge where I need to calculate the total sum of an array using the .reduce() method within a function. Instead of simply returning the sum, I am required to call a callback function and pass the sum as an argument. Though ...

Passing a C-style array of NSStrings in Objective-C syntax

Can anyone suggest the most effective way to pass a c-style array with NSString* elements to an objective-c method? This is my current approach: - (void) processArray:(NSString **) array { } - (void) execute { NSString* stringArray[2] = {@"example ...

What is the best way to update a specific value in an object without affecting the rest of

Below is a data object: { name: "Catherine Myer", age: 23, birthday: "august" } If I want to pass this data as a prop to a component, but also change the age to 24, how can I do that? <NextPage data={author.age = 24}/> The ...

Converting primary key strings to BSON for the _id field in MongoDB using Mongoskin

The primary key in Mongodb is typically _id and its data type is bson. For example: {_id : "4e7020cb7cac81af7136236b"} I am interested in setting another field's value as the primary key. For instance: apple How can I convert the string "apple" to ...

combineLatest operates independently of an observable's emission timing

I am facing an issue with two services in my application. Each service has an observable, and I have a component that is supposed to get the last emitted value of both observables. However, I noticed that the combineLatest function fires as soon as one obs ...

How can I access a TypeScript variable from a global var set in a .cshtml file?

I have defined several variables in my .cshtml file to be used in my angular services: <script> var _APIURL = '@(Url.Content("~/Admin/api/"))'; var _AREAURL = '@(Url.Content("~/Admin/"))'; var _APPURL = &a ...