2021-08-01 프로그래머스 크레인

2021-08-01
  • Algorithm
크레인

내가 접근한 풀이의 핵심은 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);
Profile picture

saengmotmi

'내가 원하는 건 문학이 아닌 기쁨이다.'