내가 접근한 풀이의 핵심은 Stack 자료 구조의 활용이다.
크레인이 쌓인 인형을 위에서부터 뽑아간다는 상황 자체가 너무나도 stack인 것이므로.
function solution(board, moves) {
// 주어진 데이터를 stack으로 다룰 수 있도록 x, y축을 변환해준다
const xyTransformedBoard = board.map((_, i) => board.map((b) => b[i]));
// 그림 좌축의 1 ~ 5까지의 영역
const stacks = [];
// 그림 우측의 결과물이 들어올 stack을 선언
const resultStack = new Stack();
// x, y를 변환한 데이터를 순회하며 stack으로 변환
for (const stack of xyTransformedBoard) {
stacks.push(new Stack(stack, resultStack));
}
// moves에 입력된 대로 해당 stack에 접근하여 pop & add
for (const move of moves) {
stacks[move - 1].pop();
}
// 결과 stack에 쌓인 인형들을 재귀적으로 라스트 팡
resultStack.distinct();
// 터진 인형 갯수를 리턴
return resultStack.deleteCount;
}
class Stack {
constructor(initState = [], resultArr) {
this.state = initState.filter((num) => num !== 0).reverse();
this.resultArr = resultArr;
this.deleteCount = 0;
}
add(item) {
this.state.push(item);
}
pop() {
const lastItem = this.state.pop();
// undefined, 0 같은 경우는 빈 칸이므로 결과로 보내지 않음
if (lastItem) {
this.resultArr.add(lastItem);
}
}
distinct() {
// 왼쪽에서부터 순회하며 연속하는 동일 인형을 검색
for (let i = 0; i < this.state.length; i++) {
const before = this.state[i];
const next = this.state[i + 1];
// 발견할 경우 터진 인행 카운트 2개 올리고, 삭제
if (before === next) {
this.deleteCount = this.deleteCount + 2;
this.state.splice(i, 2);
// 일단 검색 멈추고 다시 처음부터 검색 시작
return this.distinct();
}
}
}
}
const b = [
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 3],
[0, 2, 5, 0, 1],
[4, 2, 4, 4, 2],
[3, 5, 1, 3, 1],
];
const m = [1, 5, 3, 5, 1, 2];
solution(b, m);