[2018 카카오 블라인드] 프렌즈4블록 (JAVA)

Jiwoo Kim·2021년 3월 12일
0
post-thumbnail

문제


풀이

오.. 풀어서 한 번에 맞춰버렸다..! 인덱스를 한 번 더 디버깅하고 점검하고 제출하니 바로 통과해서 아주 뿌듯했다.

  1. initParams(): 인자들을 초기화한다.

    • board는 String 배열에서 char 2차원 배열로 변환했다. 블록들을 움직일 때 훨씬 편리하기 때문이다.
    • isPop은 삭제할 블록을 체크하는 데에 사용되는 배열이다.
  2. countPopBlocks(): pop을 할 수 있는 동안 while문을 반복하면서 삭제한 블록 개수인 count를 증가시킨다.
    a. isPopAvailable(): board를 인덱스 순서대로 돌면서 isSquareSameBlock()인지 검사한다.

    • 만약 2x2 블록을 삭제할 수 있으면 isPop 배열에 삭제할 인덱스를 체크하고 true를 리턴한다.
    • 만약 삭제할 수 있는 블록이 없으면 false가 리턴되어 반복문이 종료된다.
    • isSquareSameBlock(): NULL이 아닌 서로 같은 블록이 2x2로 모여있는지 체크한다.

    b. popAvailableBlocks(): board에 해당 블록 인덱스를 NULL 처리하고 count를 증가시킨다.

    • realignBoard(): 터뜨린 블록 자리에 위에 있는 블록을 아래로 떨어뜨린다.
    • findNextNotNullIndex(): i번째 row보다 위에 아래로 떨어뜨릴 수 있는 블록이 있는지 확인하고 인덱스를 알아낸다.
    • moveBlocksToBottom(): notNullIndex의 블록을 i번째 row로 떨어뜨린다.

코드

class Solution {
    
    private static final char NULL = '-';
    private static final int[] dy = {0, 0, 1, 1};
    private static final int[] dx = {0, 1, 0, 1};

    private int y;
    private int x;
    private char[][] board;
    private boolean[][] isPop;

    public int solution(int m, int n, String[] b) {
        initParams(m, n, b);
        return countPopBlocks();
    }
    
    private void initParams(int m, int n, String[] b){
        y = m;
        x = n;
        parseBoard(b);
        isPop = new boolean[y][x];
    }

    private void parseBoard(String[] b) {
        board = new char[y][x];
        for (int i = 0; i < y; i++)
            for (int j = 0; j < x; j++)
                board[i][j] = b[y - i - 1].charAt(j);
    }

    private int countPopBlocks() {
        int count = 0;
        while (isPopAvailable()) {
            count += popAvailableBlocks();
            isPop = new boolean[y][x];
        }
        return count;
    }

    private boolean isPopAvailable() {
        boolean flag = false;
        for (int i = 0; i < y - 1; i++)
            for (int j = 0; j < x - 1; j++)
                if (isSquareSameBlock(i, j)) {
                    checkBlocksToPop(i, j);
                    flag = true;
                }
        return flag;
    }

    private boolean isSquareSameBlock(int i, int j) {
        char now, before = NULL;
        for (int k = 0; k < 4; k++) {
            now = board[i + dy[k]][j + dx[k]];
            if (before != NULL && now != before) return false;
            before = now;
        }
        return before != NULL;
    }

    private void checkBlocksToPop(int i, int j) {
        for (int k = 0; k < 4; k++)
            isPop[i + dy[k]][j + dx[k]] = true;
    }

    private int popAvailableBlocks() {
        int count = 0;
        for (int i = 0; i < y; i++)
            for (int j = 0; j < x; j++)
                if (isPop[i][j]) {
                    board[i][j] = NULL;
                    count++;
                }
        realignBoard();
        return count;
    }

    private void realignBoard() {
        for (int i = 0; i < y; i++) {
            for (int j = 0; j < x; j++) {
                if (board[i][j] == NULL) {
                    int notNullIndex = findNextNotNullIndex(i, j);
                    if (notNullIndex != i) moveBlocksToBottom(i, notNullIndex, j);
                }
            }
        }
    }

    private void moveBlocksToBottom(int i, int notNullIndex, int j) {
        board[i][j] = board[notNullIndex][j];
        board[notNullIndex][j] = NULL;
    }

    private int findNextNotNullIndex(int i, int j) {
        int notNullIndex = i;
        while (notNullIndex >= 0 && notNullIndex + 1 < y && board[notNullIndex][j] == NULL)
            notNullIndex++;
        return notNullIndex;
    }
}

0개의 댓글