🔥 접근
- 스택에 현재 문자의 정보(문자와 인덱스)를 push하면서, 스택의 마지막 두 문자가 유효한 괄호 쌍이라면 pop 한다.
- () 쌍이 완성되면 값 2,
- [] 쌍이 완성되면 값 3을 할당하여 nums 배열에 저장한다.
- 이때 저장하는 값에는 괄호 쌍의 시작 인덱스와 끝 인덱스(range) 도 함께 저장한다.
 
- 괄호 쌍의 range에 따라 연산 방식을 결정한다.
- 괄호 쌍의 범위 길이가 1이라면 단순한 괄호 쌍이므로 덧셈 대상이 된다.
- 범위 길이가 1보다 크다면, 내부에 포함된 이전 값을 곱 연산 처리한다.
 이때, nums 배열에서 해당 범위에 완전히 포함되는 값들을 찾아 곱셈 연산을 적용한다.
 
- 모든 괄호 쌍을 처리한 뒤 스택에 요소가 남아 있다면, 유효하지 않은 괄호 문자열이므로 결과는 0이다.
- 유효한 괄호 쌍들의 값을 모두 더한 결과를 반환한다.
🧑💻 코드
const fs = require('fs');
const filePath = process.platform === 'linux' ? '/dev/stdin' : './input.txt';
const input = fs.readFileSync(filePath, 'utf8').toString().trim().split('');
const X = '()';
const Y = '[]';
const solution = (input) => {
  let pos = -1;
  const stack = [];
  const nums = [];
  input.forEach((s, idx) => {
    stack.push({
      symbol: s,
      idx,
    });
    pos += 1;
    if (pos <= 0) return;
    const fullSymbol = stack[pos - 1].symbol + stack[pos].symbol;
    if (fullSymbol === X) {
      nums.push({
        value: 2,
        range: [stack[pos - 1].idx, stack[pos].idx],
      });
      stack.pop();
      stack.pop();
      return (pos -= 2);
    }
    if (fullSymbol === Y) {
      nums.push({
        value: 3,
        range: [stack[pos - 1].idx, stack[pos].idx],
      });
      stack.pop();
      stack.pop();
      return (pos -= 2);
    }
  });
  if (stack.length > 0) return 0;
  const answerStack = [];
  nums.forEach((v) => {
    if (v.range[1] - v.range[0] === 1) answerStack.push(v);
    else {
      answerStack.forEach((item) => {
        if (item.range[0] > v.range[0] && item.range[1] < v.range[1])
          item.value *= v.value;
      });
    }
  });
  return answerStack.reduce((acc, cur) => acc + cur.value, 0);
};
console.log(solution(input));
🔗 관련 링크