q2 = input => {
let tree = [];
let stack = [];
input = input.split('');
const input2 = [];
for (let i = 0; i < input.length; i++) {
let nr = input[i].charCodeAt() - 48;
if (nr >= 0 && nr < 10) {
while (
++i < input.length &&
input[i].charCodeAt() > 47 &&
input[i].charCodeAt() < 58
) {
nr = nr * 10 + input[i].charCodeAt() - 48;
}
input2.push(BigInt(nr));
i--;
} else if (input[i] === " ") {
continue;
} else {
input2.push(input[i]);
}
}
input = input2;
for (let i = 0; i < input.length; i++) {
let token = input[i];
if (token === "(") {
stack.push(tree);
tree = [];
} else if (token === ")") {
const tree0 = stack.pop();
tree0.push(tree);
tree = tree0;
} else {
tree.push(token);
}
}
const walkTreeMul = ast => {
let mul = [];
for (let i = 0; i < ast.length; i++) {
if (Array.isArray(ast[i])) ast[i] = walkTreeMul(ast[i]);
else if (ast[i] === "*") mul.push(i);
}
if (!mul.length) return ast;
let out = ["*"];
let j = 0;
for (let i = 0; i < mul.length; i++) {
const k = mul[i];
out.push(ast.slice(j, k));
j = k + 1;
}
out.push(ast.slice(j));
return out;
};
tree = walkTreeMul(tree);
const walkTreePlus = ast => {
let sum = [];
for (let i = 0; i < ast.length; i++) {
if (Array.isArray(ast[i])) ast[i] = walkTreePlus(ast[i]);
else if (ast[i] === "+") sum.push(i);
}
if (!sum.length) return ast;
let out = ["+"];
let j = 0;
for (let i = 0; i < sum.length; i++) {
const k = sum[i];
out.push(ast.slice(j, k));
j = k + 1;
}
out.push(ast.slice(j));
return out;
};
tree = walkTreePlus(tree);
const inline = ast => {
if (Array.isArray(ast[0])) return inline(ast[0]);
for (let i = 1; i < ast.length; i++) {
ast[i] = inline(ast[i]);
}
return ast;
};
tree = inline(tree);
const calc = ast => {
let prefix = ast[0];
if (typeof prefix === "bigint") return prefix;
else {
let acc = calc(ast[1]);
if (prefix === "*") {
for (let i = 2; i < ast.length; i++) {
acc *= calc(ast[i]);
}
} else if (prefix === "+") {
for (let i = 2; i < ast.length; i++) {
console.log({ i, acc });
acc += calc(ast[i]);
}
} else {
return "there be either bugs or bad input here";
}
return acc;
}
};
return { tree, res: calc(tree) };
}