본문 바로가기

Programmers

[프로그래머스][JAVA]Lv. 2 - 프렌즈4블록

https://school.programmers.co.kr/learn/courses/30/lessons/17679

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

2 × 2 형태로 4개가 붙어있을 경우 사라지면서 점수를 얻는 게임

빈 공간을 채운 후에 다시 2 × 2 형태로 같은 모양의 블록이 모이면 다시 지워지고 떨어지고를 반복하게 된다.

char[][] arrayBoard = new char[m][n];

for (int i = 0; i < m; i++) {
    for (int j = 0; j < n; j++) {
        arrayBoard[i][j] = board[i].charAt(j);
    }
}

일단 2차원 배열 arrayBoard에 주어진 board를 저장하였다.

boolean[][] target = new boolean[m][n];

for (int i = 0; i < m - 1; i++) {
    for (int j = 0; j < n - 1; j++) {
        if (arrayBoard[i][j] != 0 &&
            arrayBoard[i][j] == arrayBoard[i + 1][j] &&
            arrayBoard[i][j] == arrayBoard[i][j + 1] &&
            arrayBoard[i][j] == arrayBoard[i + 1][j + 1]
        ) {
            target[i][j] = true;
            target[i + 1][j] = true;
            target[i][j + 1] = true;
            target[i + 1][j + 1] = true;
        }
    }
}

arrayBoard와 같은 크기의 boolean 배열 target을 만들고,

m - 1, n - 1까지 i + 1, j + 1에 의해 index가 넘어가지 않도록 2중 for문을 동작.

해당 위치 [ i ][ j ]가 null이 아니면서, [ i + 1 ][ j ], [ i ][ j + 1], [ i + 1][ j + 1]과 같을 경우

target에 해당하는 4개 [ i ][ j ], [ i + 1 ][ j ], [ i ][ j + 1], [ i + 1][ j + 1]를 true로 해줬다.

이렇게 삭제할 블록을 찾아내고

int cnt = 0;
for (int i = 0; i < m; i++){
    for (int j = 0; j < n; j++){
        if (target[i][j])
            cnt++;
    }
}
answer += cnt;
if (cnt == 0)
    break;

target이 true인 경우에 cnt 증가해 주고 삭제할 블록을 모두 세줬으면 answer에 cnt의 값을 추가,

만약 cnt가 증가하지 않았다면 삭제할 블록이 없다고 판단하고 while 문을 break 해준다.

ArrayList<Character>[] al = new ArrayList[n];
for (int i = 0; i < n; i++){
    al[i] = new ArrayList<>();
    for (int j = m - 1; j >= 0; j--){
        if (!target[j][i]){
            al[i].add(arrayBoard[j][i]);
        }
    }
}

arrayBoard = new char[m][n];
for (int i = 0; i < n; i++) {
    for (int j = m - 1; j >= 0; j--) {
        if (!al[i].isEmpty()) {
            arrayBoard[j][i] = al[i].get(0);
            al[i].remove(0);
        }
    }
}

target이 false인 블록들을 y축을 중심으로 아래에서부터 ArrayList[] al에 저장하였다.

그리고 arrayBoard를 초기화해주고 다시 arrayBoard에 al에 저장된 값들을 넣어주었다.

이것을 없앨 블록을 세는 단계에서 break가 될 때까지 반복...

import java.util.ArrayList;
class Solution {
    public int solution(int m, int n, String[] board) {
        int answer = 0;
        char[][] arrayBoard = new char[m][n];

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                arrayBoard[i][j] = board[i].charAt(j);
            }
        }

        while (true) {
            boolean[][] target = new boolean[m][n];

            for (int i = 0; i < m - 1; i++) {
                for (int j = 0; j < n - 1; j++) {
                    if (arrayBoard[i][j] != 0 &&
                        arrayBoard[i][j] == arrayBoard[i + 1][j] &&
                        arrayBoard[i][j] == arrayBoard[i][j + 1] &&
                        arrayBoard[i][j] == arrayBoard[i + 1][j + 1]
                    ) {
                        target[i][j] = true;
                        target[i + 1][j] = true;
                        target[i][j + 1] = true;
                        target[i + 1][j + 1] = true;
                    }
                }
            }

            int cnt = 0;
            for (int i = 0; i < m; i++){
                for (int j = 0; j < n; j++){
                    if (target[i][j])
                        cnt++;
                }
            }
            answer += cnt;
            if (cnt == 0)
                break;

            ArrayList<Character>[] al = new ArrayList[n];
            for (int i = 0; i < n; i++){
                al[i] = new ArrayList<>();
                for (int j = m - 1; j >= 0; j--){
                    if (!target[j][i]){
                        al[i].add(arrayBoard[j][i]);
                    }
                }
            }

            arrayBoard = new char[m][n];
            for (int i = 0; i < n; i++) {
                for (int j = m - 1; j >= 0; j--) {
                    if (!al[i].isEmpty()) {
                        arrayBoard[j][i] = al[i].get(0);
                        al[i].remove(0);
                    }
                }
            }
        }

        return answer;
    }
}