[코딩테스트 - Java] 프로그래머스 - [1차] 프렌즈4블록

김수빈·2022년 8월 18일
0

코딩테스트

목록 보기
6/16

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

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

import java.util.*;
class Solution {
    // 구현
    // 2 x 2 가 같은지 확인하는 메소드 필요
    // 맨 왼쪽 위 를 기준으로 탐색. 오른쪽, 아래, 오른쪽 아래 가 같으면 됨
    // 우선 지우지 말고, 모두 탐색 하면서 좌표의 위치를 기억
    // 마지막에 해당 좌표의 4개 점을 삭제
    // 위에서 아래로 떨어지는 메소드 구현
    static char[][] charBoard;
    
    public int solution(int m, int n, String[] board) {
    	
        // 보드 배열 생성
        charBoard = new char[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                charBoard[i][j]=board[i].charAt(j);
            }
        }
        
        int count=0;
        
        while(true){
        
            // 1. 4개가 같은 블록이 있는지 탐색 후 해당 블록의 왼쪽 위 좌표를 array에 저장
            ArrayList<int[]> array = new ArrayList<>();
            for(int i=0;i<m-1;i++){
                for(int j=0;j<n-1;j++){
                    if(isSame(i,j)){
                        array.add(new int[]{i,j});
                    }
                }
            }
            
            // 2. 탐색결과 4칸이 동일한게 없으면 array에 값이 추가가 안되므로 반복문 종료
            if(array.size()==0){
                break;
            }
            
            // 3. 동일한 칸 4칸을 지우고, 지우면서 카운트 늘림
            for(int i=0;i<array.size();i++){
                    count+=change4Block(array.get(i)[0],array.get(i)[1]);
            }
            
            // 4. 지워진 부분에 떨어지기 처리
            fallEmptySpace();
            
        }
        
        return count;
    }
    
    // 해당 좌표의 오른쪽, 아래, 오른쪽 아래 블록이 같은지 판별
    public static boolean isSame(int x, int y){

        char s = charBoard[x][y];
        if(s=='x'){
            return false;
        }
        char r = charBoard[x][y+1];
        char d = charBoard[x+1][y];
        char rd = charBoard[x+1][y+1];
        
        if(s!=r || s!=d || s!=rd){
            return false;
        }
        return true;
    }
    
    // 좌표 기준으로 4칸을 변경하고 변경된 갯수를 리턴
    // 4칸 블록이 겹쳐있는 경우가 있을 수 있음
    public static int change4Block(int x, int y){
        int count=0;
        
        // 이미 변경되지 않은 상태일 때 갯수 추가
        if(charBoard[x][y]!='x'){
            count++;
        }
        if(charBoard[x][y+1]!='x'){
            count++;
        }
        if(charBoard[x+1][y]!='x'){
            count++;
        }
        if(charBoard[x+1][y+1]!='x'){
            count++;
        }
        
        // 4칸 값 변경
        charBoard[x][y] = 'x';
        charBoard[x][y+1] = 'x';
        charBoard[x+1][y] = 'x';
        charBoard[x+1][y+1] = 'x';
        
        return count;
    }
    
    // 빈 공간으로 떨어지는 메소드
    public static void fallEmptySpace(){
    	// 'x' 의 삭제를 위해 만든 ArrayList
        ArrayList<Character> zArray = new ArrayList<>();
        zArray.add('x');
        
        // 열이 같은 부분을 시작
        for(int i=0;i<charBoard[0].length;i++){
            
            // 해당 열을 아래에서부터 ArrayList 에 추가
            ArrayList<Character> array = new ArrayList<>();
            for(int j=charBoard.length-1;j>=0;j--){
                array.add(charBoard[j][i]);
            }
            
            // 해당 열에서 'x' 가 된 부분을 삭제         
            int size = array.size();
            array.removeAll(zArray);
            
            // 다시 보드의 길이에 맞게 'x' 를 추가
            // 떨어지기 전 블록의 위치가 'x' 로 바뀌는 것
            while(array.size()<size){
                array.add('x');
            }
          	
            //만든 ArrayList를 보드에 적용
            for(int m = 0; m<array.size(); m++){
                charBoard[m][i] = array.get(size-m-1);
            }    
        }
        
        return;
    }
    
    // 테스트용 프린트 메소드
    public static void printBoard(char[][] board){
        for(char[] data : board){
            for(char d : data){
                System.out.print(d+" ");
            }
            System.out.println();
        }
        System.out.println();
    }
}

0개의 댓글