문제링크
https://programmers.co.kr/learn/courses/30/lessons/17679
블라인드 공채를 통과한 신입 사원 라이언은 신규 게임 개발 업무를 맡게 되었다. 이번에 출시할 게임 제목은 "프렌즈4블록".
같은 모양의 카카오프렌즈 블록이 2×2 형태로 4개가 붙어있을 경우 사라지면서 점수를 얻는 게임이다.만약 판이 위와 같이 주어질 경우, 라이언이 2×2로 배치된 7개 블록과 콘이 2×2로 배치된 4개 블록이 지워진다. 같은 블록은 여러 2×2에 포함될 수 있으며, 지워지는 조건에 만족하는 2×2 모양이 여러 개 있다면 한꺼번에 지워진다.
블록이 지워진 후에 위에 있는 블록이 아래로 떨어져 빈 공간을 채우게 된다.
만약 빈 공간을 채운 후에 다시 2×2 형태로 같은 모양의 블록이 모이면 다시 지워지고 떨어지고를 반복하게 된다.
위 초기 배치를 문자로 표시하면 아래와 같다.
각 문자는 라이언(R), 무지(M), 어피치(A), 프로도(F), 네오(N), 튜브(T), 제이지(J), 콘(C)을 의미한다
입력으로 블록의 첫 배치가 주어졌을 때, 지워지는 블록은 모두 몇 개인지 판단하는 프로그램을 제작하라.
- 입력으로 판의 높이 m, 폭 n과 판의 배치 정보 board가 들어온다.
- 2 ≦ n, m ≦ 30
- board는 길이 n인 문자열 m개의 배열로 주어진다. 블록을 나타내는 문자는 대문자 A에서 Z가 사용된다.
function solution(m, n, board) {
let answer = 0;
let reArr = [];
for(let i=0; i<n; i++){
let str = "";
for(let j=0; j<m; j++) str += board[j][i];
reArr.push(str);
}
reArr = reArr.map(v => v.split("").reverse().join(""));
let cnt = -1;
let common = [];
while(cnt != 0){
for(let i=1; i<reArr.length; i++){
for(let j=1; j<reArr[i].length; j++){
if(reArr[i][j] == reArr[i-1][j] && reArr[i][j] == reArr[i][j-1]
&& reArr[i][j] == reArr[i-1][j-1]) common.push([i,j])
}
}
common.map(v => {
const[a,b] = v;
reArr[a-1] = reArr[a-1].substring(0, b-1) + "00" + reArr[a-1].substring(b+1);
reArr[a] = reArr[a].substring(0, b-1) + "00" + reArr[a].substring(b+1);
})
let sum = 0;
reArr.map(v => sum += v.split("").filter(e => e == "0").length);
cnt = sum;
answer += cnt;
reArr = reArr.map(v => v.split("").filter(e => e != "0").join(""));
common = [];
}
return answer;
}
function solution(m, n, board) {
board = board.map(v => v.split(''));
while (true) {
let founded = [];
// 찾기
for (let i = 1; i < m; i++) {
for (let j = 1; j < n; j++) {
if (board[i][j] && board[i][j] === board[i][j - 1] && board[i][j] === board[i - 1][j - 1] && board[i][j] === board[i - 1][j]) {
founded.push([i, j]);
}
}
}
if (! founded.length) return [].concat(...board).filter(v => ! v).length;
// 부수기
founded.forEach(a => {
board[a[0]][a[1]] = 0;
board[a[0]][a[1] - 1] = 0;
board[a[0] - 1][a[1] - 1] = 0;
board[a[0] - 1][a[1]] = 0;
});
// 재정렬
for (let i = m - 1; i > 0; i--) {
if (! board[i].some(v => ! v)) continue;
for (let j = 0; j < n; j++) {
for (let k = i - 1; k >= 0 && ! board[i][j]; k--) {
if (board[k][j]) {
board[i][j] = board[k][j];
board[k][j] = 0;
break;
}
}
}
}
}
}
일단 문자열을 배열로 만들어서 해당 같은 알파벳이 있으면 0으로 만들어주고 0인 수의 자리를 바꿔준다.
function solution(m, n, board) {
let answer = 0;
let reArr = [];
for(let i=0; i<n; i++){
let str = "";
for(let j=0; j<m; j++) str += board[j][i];
reArr.push(str);
}
reArr = reArr.map(v => v.split("").reverse().join(""));
while(true){
let common = [];
for(let i=1; i<reArr.length; i++){
for(let j=1; j<reArr[i].length; j++)
if(reArr[i][j] == reArr[i-1][j] && reArr[i][j] == reArr[i][j-1] && reArr[i][j] == reArr[i-1][j-1])
common.push([i,j])
}
common.map(v => {
const[a,b] = v;
reArr[a-1] = reArr[a-1].substring(0, b-1) + "00" + reArr[a-1].substring(b+1);
reArr[a] = reArr[a].substring(0, b-1) + "00" + reArr[a].substring(b+1);
})
reArr.map(v => answer += v.split("").filter(e => e == "0").length);
reArr = reArr.map(v => v.split("").filter(e => e != "0").join(""));
if(!common.length) return answer;
}
}