괄호의 값

문제

언어

  • JavaScript

문제 풀이 step 1

  • 우선 주어진 입력이 올바른 괄호열인지 아닌지 검사합니다.
  • 저는 검사하는 동시에 올바른 괄호열인 경우 올바른 괄호열의 최소 단위만큼 각각 분리했습니다.
  • 스택을 준비하고 여는 괄호가 들어올 경우 스택에 push 합니다.
  • 올바른 괄호열이라면 닫는 괄호가 들어왔을 때 스택에 자신에 맞는 여는 괄호가 있습니다.
    • 즉, 올바른 문자열이라면 ‘)’은 ‘(‘와 만나게 되고, ‘[‘은 ‘]’와 만나게 됩니다.
    • 이 경우가 아니라면 올바른 괄호열이 아니므로 0 을 return 합니다.

문제 풀이 step 2

  • 분리된 올바른 괄호열을 가지고 값을 계산합니다.
  • 스택을 준비합니다. 위와 마찬가지로 여는 괄호가 들어올 경우 스택에 push 합니다.
  • 닫는 괄호가 들어왔을 때
    • 스택에 맨위의 값이 자신과 맞는 여는 괄호일 경우에는 숫자로 변환 후 다시 스택에 넣습니다.
      • 이 경우는 ‘()’ 또는 ‘[]’인 경우입니다.
    • 스택의 맨위의 값이 숫자라면 pop을 하면서 여는 괄호가 나올 떄까지 반복 후 pop 한 숫자들을 합합니다.
      • 이 경우는 ‘(X)’ 또는 ‘[X]’ 또는 ‘(XY)’ 인 경우입니다.
      • 반복을 하다 여는 괄호가 ‘(‘ 이면 합한 값에 2를 곱하고, ‘[’ 이면 합한 값에 3을 곱하고 다시 스택에 넣습니다.
  • 이를 반복하면 올바른 괄호열의 값을 구할 수 있습니다.

문제 풀이 step 3

  • 저는 각 올바른 괄호열을 분리해서 값을 계산했기 때문에 구한 값들을 모두 더하고 return 해줍니다.

소스 코드

const input = require("fs").readFileSync("/dev/stdin").toString().split("\n");

// 올바른 문자열인지 체크 및 여러개의 올바른 문자열을 각각 분리
const checkAndSplit = (input) => {
	let check = true;
	const splitedArr = [];

	const stack = [];
	let before = 0;
	for (let i = 0; i < input.length; i++) {
		if (input[i] === "(") {
			stack.push("(");
		} else if (input[i] === "[") {
			stack.push("[");
		} else if (input[i] === ")") {
			if (stack[stack.length - 1] !== "(") {
				check = false;
				break;
			}
			stack.pop();
		} else if (input[i] === "]") {
			if (stack[stack.length - 1] !== "[") {
				check = false;
				break;
			}
			stack.pop();
		}

		if (stack.length === 0) {
			splitedArr.push(input.substring(before, i + 1));
			before = i + 1;
		}
	}

	return [check, splitedArr];
};

// 각각 올바른 문자열에 대해서 괄호값 계산
const calculator = (input) => {
	const stack = [];

	for (let i = 0; i < input.length; i++) {
		if (input[i] === "(" || input[i] === "[") {
			stack.push(input[i]);
		} else if (input[i] === ")" || input[i] === "]") {
			const top = stack[stack.length - 1];

			if (top === "(") {
				stack.pop();
				stack.push(2);
			} else if (top === "[") {
				stack.pop();
				stack.push(3);
			} else if (typeof top === "number") {
				const numbers = [];
				while (typeof stack[stack.length - 1] === "number") {
					numbers.push(stack.pop());
				}
				const sum = numbers.reduce((ac, v) => ac + v, 0);

				if (stack[stack.length - 1] === "(") {
					stack.pop();
					stack.push(sum * 2);
				} else if (stack[stack.length - 1] === "[") {
					stack.pop();
					stack.push(sum * 3);
				}
			}
		}
	}

	return stack[0];
};

const solution = (input) => {
	const [check, splitedArr] = checkAndSplit(input[0]);

	if (check === false) return 0;

	const resArr = splitedArr.map((v) => calculator(v));

	return resArr.reduce((ac, v) => ac + v, 0);
};

console.log(solution(input));