function solution(m, n, board) {
let newBoard = board.map(block => [...block]);
while (true) {
let count = 0;
for (let x = 0; x < m - 1; x++) {
for (let y = 0; y < n - 1; y++) {
if (board[x][y] === '') continue;
if (board[x][y] === board[x][y + 1] && board[x][y] === board[x + 1][y] && board[x][y] === board[x + 1][y + 1]) {
newBoard[x][y] = '';
newBoard[x + 1][y] = '';
newBoard[x][y + 1] = '';
newBoard[x + 1][y + 1] = '';
count += 1;
}
}
}
if (count === 0) break;
for (let x = 0; x < m - 1; x++) {
for (let y = 0; y < n; y++) {
if (newBoard[x + 1][y] === '') {
for (let i = x; i >= 0; i--) {
newBoard[i + 1][y] = newBoard[i][y];
newBoard[i][y] = '';
}
}
}
}
board = newBoard;
}
const allBoards = newBoard.reduce((acc, cur) => acc.concat(cur));
return allBoards.filter(block => block === '').length;
}
5단계(newBoard를 board에 복사한다.)에서 잘못된 점을 발견하였다.
board = newBoard
로 배열을 복사하면 원본 배열의 값을 참조하여 주소값을 공유하기 때문에 둘 중 하나를 수정하면 다른 배열도 같이 변하게 된다.
이것을 얕은 복사라고 부른다.
얕은 복사를 해서 생긴 문제는 지워지는 조건에 만족하는 2×2 모양이 여러 개 있을 때 생긴다.
예를 들어 위의 보라색 블럭 2*3을 지워야 한다.
board[2][0]
블록을 기준으로 newBoard의 블럭을 비워두었다.
이제 board[2][1]
블록을 기준으로 블럭을 비워야 한다.
그런데 newBoard가 수정될 때 board도 같이 수정되었기 때문에 board[2][1]
은 빈 블록 상태가 되어 반복문을 넘기게 된다.
따라서 board[2][2]
와 board[3][2]
는 비워지지 않고 넘어간다.
function solution(m, n, board) {
let curBoard = board.map((block) => [...block]);
let newBoard = board.map((block) => [...block]);
while (true) {
let count = 0;
for (let x = 0; x < m - 1; x++) {
for (let y = 0; y < n - 1; y++) {
if (curBoard[x][y] === '') continue;
if (
curBoard[x][y] === curBoard[x][y + 1] &&
curBoard[x][y] === curBoard[x + 1][y] &&
curBoard[x][y] === curBoard[x + 1][y + 1]
) {
newBoard[x][y] = '';
newBoard[x + 1][y] = '';
newBoard[x][y + 1] = '';
newBoard[x + 1][y + 1] = '';
count += 1;
}
}
}
if (count === 0) break;
for (let x = 0; x < m - 1; x++) {
for (let y = 0; y < n; y++) {
if (newBoard[x + 1][y] === '') {
for (let i = x; i >= 0; i--) {
newBoard[i + 1][y] = newBoard[i][y];
newBoard[i][y] = '';
}
}
}
}
curBoard = newBoard.map((block) => [...block]);
}
const allBoards = newBoard.reduce((acc, cur) => acc.concat(cur));
return allBoards.filter((block) => block === '').length;
}
board = newBoard
가 아닌 curBoard = newBoard.map((block) => [...block])
와 같이 배열을 복사한다.
map을 사용해 배열의 요소를 하나씩 복사하므로 원본 배열과 다른 주소값을 갖는 깊은 복사를 하게 된다.