const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.on("line", function (line) {
const ans: any[] = [],
len = line.length;
let i = 0,
j = 0;
const brackets: any = { ")": "(", "]": "[", "}": "{" };
const opsEnum: string[] = ["+", "-", "*", "/"];
while (j <= len) {
if ((opsEnum.includes(line[j]) && i !== j) || (i <= len - 1 && j === len)) {
// i !== j 处理前导负号的数字 (-1+2)*3-4,同时入栈数字和运算符
if (j < len) ans.push(Number(line.substring(i, j)), line[j]);
// 处理最后一个数字
if (j === len) ans.push(Number(line.substring(i, j)));
i = j + 1;
} else if (["{", "[", "("].includes(line[j])) {
ans.push(line[j]); // 左括号极端情况:{[(1 + 2 * 3 - 4) * 5 - 6] / 7 + 8}
i = j + 1;
} else if (line[j] in brackets) { // 当遇到右括号时
const arr: any[] = i < j ? [Number(line.substring(i, j))] : []; // i 可能指向行末,必须加 i < j 的判断
let pop = ans.pop();
// 把当前括号中的表达式提取出来
while (pop !== brackets[line[j]]) {
arr.unshift(pop);
pop = ans.pop();
}
// 当前括号中的表达式计算后的结果入栈
ans.push(calc(arr));
// 找到下一个数字的起始位置
if (opsEnum.includes(line[j + 1])) { // 当前括号位置的下一个位置为 运算符 时,下下个位置一定是 数字
ans.push(line[j + 1]);
i = j + 2;
++j;
} else { // 当前括号的下一个位置可能是一个中括号、大括号、行末,如 )]}
i = j + 1;
while (i < len && Number.isNaN(Number(line[i]))) ++i;
}
}
++j;
}
console.log(calc(ans));
function calc(arr: any[]): number {
if (arr.length === 1) return arr[0];
const ops: string[] = [];
// 把操作数和运算符分组
for (let i = 0; i < arr.length; ++i) {
if (arr[i].length === 1 && opsEnum.includes(arr[i])) {
ops.push(arr[i]);
arr.splice(i, 1);
}
}
// 从左到右,先处理优先级高的乘、除运算
let i = 0;
while (ops.includes("*") || ops.includes("/")) {
while (i < ops.length) {
if (ops[i] === "*" || ops[i] === "/") {
const [num1, num2]: [any, any] = [arr.splice(i, 1), arr.splice(i, 1)];
arr.splice(i, 0, ops[i] === "*" ? num1 * num2 : num1 / num2);
ops.splice(i, 1);
break;
}
++i;
}
}
// 处理加、减运算
while (ops.length !== 0) {
const [num1, num2] = [arr.shift(), arr.shift()];
const op = ops.shift();
if (op === "+") arr.unshift(num1 + num2);
if (op === "-") arr.unshift(num1 - num2);
}
return arr[0];
}
});