Basic Calculator
This problem is about evaluating a simple expression like 2 - (3 + 5). To start off, I wrote code to handle everything except parantheses. When a digit is encountered, it’s appended to the string builder. When an operator or the end of the input is encountered:
- Convert the string builder to an integer
- Apply the previous operator (
op
) on the number gotten above andprev
. - Update
prev
with the result gotten above - Reset the string builder to start parsing the next number
- Store the current operator in
op
- Continue to the next character. If end of the string, exit the loop and apply the final operation.
function calculate(s: string): number {
let sb = ''
const expr = s.replaceAll(' ', '')
let prev = 0
let op = '+'
for(let i = 0;i < expr.length;i++) {
const char = expr[i]
if(char >= '0' && char <= '9') {
sb += char
}
else {
const b = Number(sb)
prev = operate(prev, b, op)
sb = ''
op = char
}
}
const finalOperand = Number(sb)
const finalResult = String(operate(prev, finalOperand, op))
setResult(finalResult)
}
The next step was to handle paranthesis. I approached this by going through an example and noting what data I’d need in order to perform the operations in the correct order. For example:
5 + 2 - ((2 + 3) - 5)
When we encounter the first opening paranthesis, prev
is 7 and op
is -
. We want to evaluate what is in the paranthesis and then subtract it from 7. To hold this kind of information,
I created an interface named OpData
. Everytime an opening paranthesis is encountered, the current values of prev
and op
are pushed onto a stack so that they can be retrieved after the
expression in parantheses is evaluated. Also, when an opening paranthesis is encountered, op
is set to +
and prev
to 0
so that if the next character is also an opening paranthesis
{'+', 0}
will be pushed onto the stack and have no effect when it’s popped and evaluated. If the next character is not an opening paranthesis, then evaluation continues as before until
a closing paranthesis is encountered. Once that happens, the stack is popped and combined with the result of the expression in the current set of parantheses.
Here’s the final code and result.
function calculate(s: string): number {
const stack: OpData[] = []
let sb = ''
const expr = s.replaceAll(' ', '')
let prev = 0
let op = '+'
for(let i = 0;i < expr.length;i++) {
const char = expr[i]
if(char >= '0' && char <= '9') {
sb += char
}
else if(char == '(') {
stack.push({
prev: prev,
op: op
})
op = '+'
prev = 0
sb = ''
}
else if(char == ')') {
if(sb.length > 0) {
const b = Number(sb)
prev = operate(prev, b, op)
sb = ''
}
const opData = stack.pop() as OpData
prev = operate(opData.prev, prev, opData.op)
}
else {
const b = Number(sb)
prev = operate(prev, b, op)
sb = ''
op = char
}
}
const finalOperand = Number(sb)
const finalResult = String(operate(prev, finalOperand, op))
return Number(finalResult)
};
const operate = (a: number, b: number, op: string) => {
if(op == '+') {
return a + b
}
else if(op == '-') {
return a - b
}
else {
throw new Error(`Unexpected op: ${op}`)
}
}
interface OpData {
prev: number,
op: string
}

Demo
Enter an expression containing only whole numbers, +, -, (, and ) then click “Evaluate”. You can find the source code for this demo here