//1.
문자열을 배열로 쪼개주고
//2.
현재 좌표에서 2x2가 해당되는지 판별해준다.
direction을 배열로 미리 잡아두고, direction을 map 순회한 좌표를 일단 blocks 변수에 집어 넣는다.
그리고 blocks를 every 메서드로 순회하는데, block이 존재하고, 각 block이 blocks[0]과 전부 같다는 건, 2x2에 해당한다는 의미이다. 이 경우 4개의 블럭을 target 배열에 집어넣는다.
여기서 flag로 while문 종료 조건을 거는데, 2x2가 해당될때만 flag=true해주므로 2x2해당되지 않을 때는 false가 되므로 종료된다.
//3.
target 배열에 있는 요소들을 순회하는데, board[x][y]가 비어있지 않을 때만 비워주고 answer++;해줌으로써 중복을 피한다.
//4.
2x2해당하는 애들을 ''로 비워주고 난 뒤, 업데이트를 해줘야 하므로.
이번엔 가로/세로를 바꿔서 stack 배열에 세로줄 요소들(block)을 차례대로 push한다. (block이 비어있지 않을 때만)
그리고 index를 거꾸로 순회하면서 길이가 존재한다면 stack에서 pop해준 애를 board에 집어 넣는다. 비어 있다면 전체 세로줄(board[j][i]를 비워준다)
크레인 인형뽑기 문제에서의 배열을 역순으로 변경후 0을 제거하는 방법 참고해보기(여기서는 ''가 0에 해당함).
function solution(m, n, board) {
let answer = 0;
// 1.
// board = board.map(r => [...r]);
board = board.map(r => r.split(''));
const dir = [[0,0], [0,1], [1,0], [1,1]];
let flag = true;
while (flag) {
flag=false;
// 2.
const target = [];
for (let i=0; i<m-1; i++) {
for (let j=0; j<n-1; j++) {
const blocks = dir.map(([dx,dy]) => board[i+dx][j+dy]);
if (blocks.every(block => !!block && block === blocks[0])) {
dir.map(([dx,dy]) => target.push([i+dx, j+dy]));
flag=true;
}
}
}
// 3.
target.forEach(([x,y]) => {
const block = board[x][y];
if (block) {
board[x][y] = '';
answer++;
}
});
// 4.
for (let i=0; i<n; i++) {
const stack = [];
for (let j=0; j<m; j++) {
const block = board[j][i];
if (block) stack.push(block);
}
for (let j=m-1; j>=0; j--) {
if (stack.length) {
board[j][i] = stack.pop();
} else {
board[j][i] = '';
}
}
}
}
return answer;
}
console.log(solution(
4, 5, [
"CCBDE",
"AAADE",
"AAABF",
"CCBBF"]));