Game of Life

zoovely·2024년 5월 24일
0
post-thumbnail

💬 문제

[문제 링크]

0과 1로 이루어진 m * n 정수 배열 board
조건에 맞추어 board를 다음 상태로 수정

1. 살아있는 사람 주변에 살아있는 이웃이 2명 혹은 3명이라면 다음에도 살아있음
2. 살아있는 사람 주변에 살아있는 이웃이 2명보다 적다면 다음에 죽어있음
3. 살아있는 사람 주변에 살아있는 이웃이 3명보다 많다면 다음에 죽어있음
4. 죽어있는 사람 주변에 살아있는 이웃이 딱 3명이라면 다음에 살아있음

여기서 살아있다는 1, 죽어있다는 0으로 표현되며
주변은 해당 칸의 상하좌우, 대각선인 8칸을 가리킴

✍️ 나의 풀이

/**
 * @param {number[][]} board
 * @return {void} Do not return anything, modify board in-place instead.
 */
var gameOfLife = function(board) {
    for (let i = 0; i < board.length; i++) {
        for (let j = 0; j < board[0].length; j++) {
            board[i][j] = check(i, j, board);
        }
    }

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

function check(i, j, board) {
    const dirs = [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]];
    let cnt = 0;

    for (let [x, y] of dirs) {
        let val = board[i + x] ? board[i + x][j + y] : 0;
        if (val === 1 || val === 3)
            cnt++;
    }

    if (board[i][j] === 0) {
        if (cnt === 3)
            return 2;
        return 0;
    } else {
        if (cnt === 2 || cnt === 3)
            return 1;
        return 3;
    }
}

배열을 순회하면서 조건에 맞춰 값을 변경
조건을 확인하여 바뀔 값을 알려주는 함수 check
dirs에 확인해야할 주변(이웃, 8칸)과의 인덱스 차이값을 모두 넣어놓고
배열을 순회하면서 살아있다면 cnt를 증가 (조건이 모두 살아있는 사람이 주변에 몇명이냐에 따르므로)
그리고 현재 인덱스의 값과 살아있는 이웃의 수를 비교하여 다음 값을 정하는데,
즉시 값을 0이나 1로 바꾸어버리면 다음 인덱스에서의 계산 시 예측이 바뀌므로
0 -> 1이 되는 것은 2로, 1 -> 0이 되는 것은 3으로 기록하여
다른 인덱스가 참조시 2면 죽어있는 상태, 3이면 살아있는 상태로 계산하게끔 함
모든 칸의 값을 변경했으면 마지막으로 2와 3을 1과 0으로 바꾸는 작업 진행

📌 결과

Accepted
Runtime 50ms (Beats 78.31%)
Memory 50.84MB (Beats 28.06%)

📚 러닝 포인트

이전 문제와 비슷한 부분이 많아서 이번에는 바로바로 인덱스 값을 업데이트하는 방법을 사용해봤다. 주변 8칸을 확인하는 부분에서 하나씩 다 확인하고 계산하는 방법으로 작성했더니 너무 중복된 부분이 많고 지저분해서 배열을 활용했다. 물론 솔루션의 도움을 조금 받았다... 그리고 이 부분 구현하면서 원래 알고 있었지만 조금 더 정확하게 알게된게 있는데, 이전 몇 문제들에서 1차원 배열에 없는 인덱스를 참조했을 때 참조 에러가 아닌 undefined가 나오는 현상을 활용한 적이 있다. 하지만 2차원 배열에서는 행, 그러니까 board[i]를 참조할 때 i가 총 길이보다 클 때 참조값이 undefined로 나오지만, 그 뒤에 열 인덱스를 붙여버리면 참조 에러가 발생한다. 당연하다. undefined는 배열이 아니므로 인덱스를 참조할 수 없다. 그래서 let val = board[i + x] ? board[i + x][j + y] : 0; 이 부분에서 행의 존재를 확인하고 열 인덱스까지 확인하면 된다. undefined라면 0으로 저장하게끔. 습관처럼 당연히 알고있어야 하는 부분인데 어쩐지 코드를 작성하다보면 그 부분을 까먹고 참조 에러를 자주 만나기도 한다...

profile
나도 할 수 있을까?

0개의 댓글