[프로그래머스/Javascript] 프렌즈4블록

알고리즘 - 배열 다루기

Posted by Kyun2da on July 5, 2020

1️⃣서론

프로그래머스 level2 문제 [1차] 프렌즈4블록입니다. Javascript를 이용하여 해결하였습니다.

2️⃣문제 설명

프렌즈블록1 프렌즈블록2 프렌즈블록3 프렌즈블록4

3️⃣풀이

이문제는 푸는 원리는 다들 쉽게 이해할 테지만 구현력을 상당히 요구하는 문제였습니다. 문제 설명을 그대로 따라가며 알고리즘을 구현하면 되지만 배열에 익숙하지 않다면 많이 헤매야 했고, 풀이는 다음과 같습니다.

  1. 먼저 배열의 문자열을 2차원 배열로 나눕니다.
  2. 배열에서 지워질 블록의 인덱스를 구해 arr안에 넣습니다.
  3. 배열에서 지워질 블록을 0으로 바꿉니다.
  4. 깨진 블록을 없애고 위에서 블록을 당겨옵니다. (이 부분의 로직이 어려운데 먼저 위에서 가져올 블록이 있는지 검사합니다.)

4️⃣ 내가 푼 소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
const solution = (m, n, board) => {
  let answer = 0;
  //1. 먼저 배열의 문자열을 2차원 배열로 나눈다.
  board = board.map((v) => v.split(""));

  //2. 배열에서 지워질 블록의 인덱스를 구해 arr안에 넣는다.
  while (true) {
    const arr = [];
    for (let i = 0; i < m - 1; i++) {
      for (let j = 0; j < n - 1; j++) {
        if (
          board[i][j] &&
          board[i][j] === board[i + 1][j] &&
          board[i][j] === board[i][j + 1] &&
          board[i][j] === board[i + 1][j + 1]
        ) {
          arr.push([i, j]);
        }
      }
    }
    // 답을 구하는 로직 : 깨질 블록이 없다면 0인 개수를 세고 리턴한다.
    if (!arr.length) {
      return [].concat(...board).filter((v) => !v).length;
    }

    // 3. 배열에서 지워질 블록을 0으로 바꾼다.
    for (let i = 0; i < arr.length; i++) {
      const col = arr[i][0];
      const row = arr[i][1];
      board[col][row] = 0;
      board[col][row + 1] = 0;
      board[col + 1][row] = 0;
      board[col + 1][row + 1] = 0;
    }

    // 4. 깨진 블록을 없애고 위에서 블록을 당겨온다.
    for (let i = m - 1; i > 0; i--) {
      if (!board[i].some((v) => !v)) continue;

      for (let j = 0; j < n; j++) {
        for (let k = i - 1; k >= 0 && !board[i][j]; k--) {
          if (board[k][j]) {
            board[i][j] = board[k][j];
            board[k][j] = 0;
            break;
          }
        }
      }
    }
  }
};

5️⃣ 결론

4번 로직이 좀 어려운데 배열에 대한 조건들을 잘 생각해보고 따져봐야 통과할 수 있는 문제였던 것 같습니다.

6️⃣ 마치며..

질문과 지적은 환영합니다. 이 문제는 최적의 정답일 수도 아닐수도 있습니다.
궁금한게 있으시면 아래 댓글 남겨주세요.🙏
댓글은 저에게 큰 힘이 됩니다!
감사합니다. ❤️