프로그래머스 [1차] 프렌즈4블록

·2022년 4월 2일
1

문제

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

만약 판이 위와 같이 주어질 경우, 라이언이 2×2로 배치된 7개 블록과 콘이 2×2로 배치된 4개 블록이 지워진다. 같은 블록은 여러 2×2에 포함될 수 있으며, 지워지는 조건에 만족하는 2×2 모양이 여러 개 있다면 한꺼번에 지워진다.
블록이 지워진 후에 위에 있는 블록이 아래로 떨어져 빈 공간을 채우게 된다.
만약 빈 공간을 채운 후에 다시 2×2 형태로 같은 모양의 블록이 모이면 다시 지워지고 떨어지고를 반복하게 된다.
위 초기 배치를 문자로 표시하면 아래와 같다.
TTTANT
RRFACC
RRRFCC
TRRRAA
TTMMMF
TMMTTJ
각 문자는 라이언(R), 무지(M), 어피치(A), 프로도(F), 네오(N), 튜브(T), 제이지(J), 콘(C)을 의미한다
입력으로 블록의 첫 배치가 주어졌을 때, 지워지는 블록은 모두 몇 개인지 판단하는 프로그램을 제작하라.


코드

import java.io.*;
import java.util.HashSet;

import static java.util.Objects.hash;

class Solution {
    public class RowColumn{
        public int row;
        public int column;

        public RowColumn(int row, int column) {
            this.row = row;
            this.column = column;
        }

        @Override
        public boolean equals(Object obj) {
            return this.hashCode()==obj.hashCode();
        }

        @Override
        public int hashCode() {
            return hash(row, column);
        }
    }

    public int solution(int m, int n, String[] board) { //row m, column n, board.size m
        int answer = 0;
        int[][] array=new int[m][n];
        for(int i=0; i<m; i++)
            for(int j=0; j<n; j++)
                array[i][j]=board[i].charAt(j);

        while (true) {
            HashSet<RowColumn> broken = new HashSet<>();
            for (int i = 0; i < m - 1; i++) {
                int column=1;
                while(column<n&&array[i][column]==0)
                    column++;

                for (int j = column; j < n; j++) {
                    int previous = array[i][j-1];
                    if(previous==0)
                        continue;

                    if (array[i][j] == previous && array[i+1][j-1] == previous && array[i+1][j] == previous) {
                        broken.add(new RowColumn(i, j-1));
                        broken.add(new RowColumn(i, j));
                        broken.add(new RowColumn(i+1, j-1));
                        broken.add(new RowColumn(i+1, j));
                    }
                    while(j<n&&array[i][j-1]==0)
                        j++;
                }
            }
            if(broken.isEmpty())
                break;
            answer += broken.size();

            for(RowColumn i:broken)
                array[i.row][i.column]=0;

            for(int i=0; i<n; i++){
                for(int j=m-1; j>0; j--){
                    if(array[j][i]==0){
                        int row=j;
                        while(row>0&&array[--row][i]==0){}
                        if(array[row][i]!=0) {
                            array[j][i] = array[row][i];
                            array[row][i] = 0;
                        }
                    }
                }
            }
        }

        return answer;
    }
}

해결 과정

  1. 처음에는 단순히 4개 모여 있는 블록들만 제거하면 되는 줄 알았다. HashSet을 사용해서 중복 없이 모여 있는 블록들을 제거하고 answer에 더해줬다. 모든 테스트 케이스를 실패했고, 문제를 다시 읽었다...ㅠㅠ

    모든 블록들을 제거하고 제거한 자리에 0을 대입한 뒤, 아래층 블록부터 탐색하며 빈 공간들을 끌어 내리려고 했다.

    solution의 인자가 String으로 주어지기 때문에 String 클래스를 사용해서 블록 채우기를 하면 느릴 것 같아서 새로 int형 2차원 배열을 선언했다. 그리고 아래층부터 탐색하며 빈 공간이 있으면 채우고 다시 블록 터뜨리기를 반복했다.
    만일 터진 블록이 하나도 없으면(broken.size()==0) return 한다.

  1. 😁

profile
渽晛

0개의 댓글