Welcome to the repository for my RPN calculator. You can see it in action at https://webdevred.github.io/rpn-calculator/
Continue reading for information for about how it works,
when it comes to HTML we need two things
- input where the user can enter a expression
- a span where we store the result
<input id="expression">
Result: <span id="result"></span>
- when page has loaded, query the page for those elements
- when user releases a key while in the form fetch the value and give that value to solveRPN.
- set the innerText of the result span to the result of step 2.
window.onload = () => {
const expressionInput = document.querySelector("#expression");
const resultSpan = document.querySelector("#result");
expressionInput.onkeyup = () => resultSpan.innerText = solveRPN(expressionInput.value);
};
- split the expression which is a string into a array of strings
- reduce/fold over the the array
- the folding function takes two arguments being stack and single
- stack will be be the accumulator being [] and single will be a operator or a number
- if single is a number put it in the stack, if it is a operator perform the operation on the two newest numbers, then put that result in the stack
- verify there is only one result, otherwise smth is wrong
const solveRPN = (expression) => {
let resultArray = expression.split(" ").reduce(reducingFun, []);
if (resultArray.length === 1) {
return resultArray[0];
} else {
return "";
}
};
const reducingFun = (stack, single) => {
if (isNumeric(single)) return [single, ...stack];
let [y, x] = stack.slice(0, 2);
if (!isNumeric(x) && !isNumeric(y)) return [];
let rest = stack.slice(2);
switch (single) {
case "+":
return [parseFloat(x) + parseFloat(y), ...rest];
case "*":
return [parseFloat(x) * parseFloat(y), ...rest];
case "-":
return [parseFloat(x) - parseFloat(y), ...rest];
case "/":
return [parseFloat(x) / parseFloat(y), ...rest];
case "^":
return [Math.pow(parseFloat(x), parseFloat(y)), ...rest];
}
};
const isNumeric = (str) => {
if (typeof str != "string") return false
return !isNaN(str) && !isNaN(parseFloat(str))
};
console.log(solveRPN("2 2 +"));
console.log(solveRPN("5 2 -"));
console.log(solveRPN("10 5 /"));
console.log(solveRPN("10 4 3 + 2 * -"));
body {
background-color: #DD7F7A;
color: #EBE8D6;
}
header, .main-container {
max-width: 1050px;
margin: 0 auto;
}
.main-container {
display: flex;
}
main {
flex: 75%;
}
aside img {
border: 3px solid #EBE8D6;
}