프로그래머스 프렌즈4블록 JavaScript
2023년 5월 17일
문제 풀이
카카오프렌즈 블록이 2x2 형태로 4개가 붙어있을 경우 사라지면서 점수를 얻는 게임이다. 4개의 블록이 같은 블록으로 사라지면 위 블록들이 아래로 떨어져 빈 공간을 채운다. 떨어진 후 다시 2x2 형태로 같은 모양의 블록이 모이면 다시 지워지고 떨어지고를 반복한다.
우선 2x2 형태로 같은 모양의 블록을 찾는다. 없는 경우 종료하고, 찾은 경우에는 찾은 블록들을 빈 블록으로 바꿔준다.
이후 빈 블록들의 위에 위치한 블록들을 아래로 내려준다. 2x2 형태의 같은 모양의 블록이 없을 때까지 반복한다.
const board_split = board.map(item => item.split(''));
: 매개변수 board
는 문자열이 저장되어 있는 배열이므로, 블록의 손쉬운 변경을 위해 split 하여 2차원 배열의 형태로 저장한다.
함수:
findBlock()
:board_split
를 순회하면서 2x2 형태로 같은 모양의 블록을 찾아 해당 블록의 맨 왼쪽, 맨 위의 인덱스들의 배열을 반환하는 함수.
현재 위치에서 2x2 블록을 확인하기에m - 1
,n - 1
만큼board_split
을 순회한다. 현재 위치의 값이 빈 문자열이면 다음으로 이동하고, 빈 문자열이 아닌 경우에는 현재 위치에서 2x2 블록들의 값이 같은 경우 2x2 형태의 같은 모양의 블록이므로answer
에 [h, w] 형태로 push.lowerBlock()
:board_split
에 빈 문자열이 있을 때, 해당 위치 위에 위치한 문자열들이 빈 문자열이 아닌 경우 아래로 내려주는 함수.board_split
의 폭n
을 순회할 때, 조회하는 값 중(높이:m
)에 빈 문자열이 있으면 빈 문자열을 맨 위로 이동시킨다.
solution.js
function solution(m, n, board) {
let answer = 0;
const board_split = board.map(item => item.split(''));
const findBlock = () => {
const answer = [];
for (let h = 0; h < m - 1; h ++) {
for (let w = 0; w < n - 1; w++) {
const character = board_split[h][w];
if (character === ' ') continue;
if (board_split[h][w + 1] === character && board_split[h + 1][w] === character && board_split[h + 1][w + 1] === character) {
answer.push([h, w]);
}
}
}
return answer;
};
const lowerBlock = () => {
for (let w = 0; w < n; w++) {
for (let h = 0; h < m; h++) {
if (board_split[h][w] === ' ') {
for (let k = h; k > 0; k--) {
const temp = board_split[k][w];
board_split[k][w] = board_split[k - 1][w];
board_split[k - 1][w] = temp;
}
}
}
}
};
while (true) {
const blockIndex = findBlock();
if (blockIndex.length === 0) break;
blockIndex.forEach(indexs => {
const [x, y] = indexs;
for (let dx = 0; dx < 2; dx++) {
for (let dy = 0; dy < 2; dy++) {
answer += board_split[x + dx][y + dy] === ' ' ? 0 : 1;
board_split[x + dx][y + dy] = ' ';
}
}
});
lowerBlock();
}
return answer;
}