💡Problem Solving/Programmers

[프로그래머스] 프렌즈4블록 (Java)

gom20 2021. 10. 23. 14:50

#문제

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

 

코딩테스트 연습 - [1차] 프렌즈4블록

프렌즈4블록 블라인드 공채를 통과한 신입 사원 라이언은 신규 게임 개발 업무를 맡게 되었다. 이번에 출시할 게임 제목은 "프렌즈4블록". 같은 모양의 카카오프렌즈 블록이 2×2 형태로 4개가 붙

programmers.co.kr

 

#풀이

순서대로 배열을 체크해서 풀었다. 

블록을 2차배열에 저장하고, 인덱스의 우측, 아래쪽, 대각선우측을 체크하여 삭제할 인덱스를 리스트에 담아둔다. 

삭제할 리스트의 크기가 0이면 while문을 빠져나온다. 

삭제할 블록이 있다면 한꺼번에 공백으로 바꿔준다. 

이후 블록을 체크하면서 현재 블록의 밑 블록이 비어 있는지 체크하여, 블록을 떨어트린다. 

 

#소스코드

 

import java.util.ArrayList;

class Solution {
    public char[][] boards;
    public int m = 0, n = 0;
    public int[][] dir = new int[][]{{0, 1}, {1, 0}, {1, 1}};
    public int solution(int n, int m, String[] board) {
        int answer = 0;
        // 2차 배열로 변경
        boards = new char[n][m];
        for(int i = 0; i < board.length; i++){
            this.boards[i] = board[i].toCharArray();
        }
        this.n = n;
        this.m = m;

        ArrayList<int[]> delList = new ArrayList<int[]>();
        while(true){
            delList.clear();
            // 지울 수 있는지 체크하여 Index를 저장해 둔다. 
            for(int i = 0; i< boards.length; i++){
                for(int j = 0; j < boards[i].length; j++){
                    if(canDelete(i, j, boards[i][j])) delList.add(new int[]{i, j});
                }
            }
            if(delList.size() == 0) break;

            // 한 꺼번에 다 지운다.
            for(int[] idxes : delList){
                int x = idxes[0];
                int y = idxes[1];
                boards[x][y] = '\0';
                for(int[] d : dir){
                    boards[x + d[0]][y + d[1]] = '\0';
                }
            }

            // 블록을 떨어트린다. 
            for(int i = boards.length-2; i >= 0; i--){
                for(int j = 0 ; j < boards[i].length; j++){
                    if(boards[i][j] != '\0' && boards[i+1][j] == '\0'){
                        int ni = i;
                        while(true){
                            ni++;
                            if(ni >= n) break;
                            if(boards[ni][j] != '\0') break;
                        }
                        boards[ni-1][j] = boards[i][j];
                        boards[i][j] = '\0';
                    }
                }
            }
        }

        for(int i= 0; i < boards.length; i ++){
            for(int j = 0; j < boards[i].length ;j ++){
                if(boards[i][j] == '\0') answer++;
            }
        }
        
        return answer;
    }

    public void printBlock(){
        for(int i= 0; i < boards.length; i++){
            System.out.println();
            for(int j = 0; j < boards[i].length; j++){
                System.out.print(boards[i][j] + " ");
            }
        }
        System.out.println();
    }

    public boolean canDelete(int x, int y, char val){
        // 오른쪽, 오른쪽 대각선, 아래 확인
        if(boards[x][y] == '\0') return false;
        for(int[] d : dir) {
            int nx = x + d[0];
            int ny = y + d[1];
            if(nx < 0 || ny < 0 || nx >= n || ny >= m) return false;
            if(boards[nx][ny] != val) return false;
        }
        return true;
    }
}