블라인드 공채를 통과한 신입 사원 라이언은 신규 게임 개발 업무를 맡게 되었다. 이번에 출시할 게임 제목은 "프렌즈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;
}
}
처음에는 단순히 4개 모여 있는 블록들만 제거하면 되는 줄 알았다. HashSet을 사용해서 중복 없이 모여 있는 블록들을 제거하고 answer에 더해줬다. 모든 테스트 케이스를 실패했고, 문제를 다시 읽었다...ㅠㅠ
모든 블록들을 제거하고 제거한 자리에 0을 대입한 뒤, 아래층 블록부터 탐색하며 빈 공간들을 끌어 내리려고 했다.
solution의 인자가 String으로 주어지기 때문에 String 클래스를 사용해서 블록 채우기를 하면 느릴 것 같아서 새로 int형 2차원 배열을 선언했다. 그리고 아래층부터 탐색하며 빈 공간이 있으면 채우고 다시 블록 터뜨리기를 반복했다.
만일 터진 블록이 하나도 없으면(broken.size()==0) return 한다.