Skip to content

Instantly share code, notes, and snippets.

@rebolyte
Last active September 29, 2017 20:08
Show Gist options
  • Save rebolyte/ded01a006da20b21bbbe to your computer and use it in GitHub Desktop.
Save rebolyte/ded01a006da20b21bbbe to your computer and use it in GitHub Desktop.
Evaluate a string in Reverse Polish Notation and output the result.
// https://codegolf.stackexchange.com/questions/221/reverse-polish-notation
'use strict';
// let s = '-4 5 +';
// let s = '5 2 /';
// let s = '5 2.5 /';
// let s = '4 2 5 * +';
// let s = '5 1 2 + 4 * 3 - +';
let s = '4 2 5 * + 1 3 2 * + /';
function evalPostfix(expr /* Array of [num num op] */) {
switch (expr[2]) {
case '+':
return parseFloat(expr[0]) + parseFloat(expr[1]);
break;
case '-':
return parseFloat(expr[0]) - parseFloat(expr[1]);
break;
case '/':
return parseFloat(expr[0]) / parseFloat(expr[1]);
break;
case '*':
return parseFloat(expr[0]) * parseFloat(expr[1]);
break;
default:
// console.log('number');
break;
}
}
var ops = ['+', '-', '*', '/'];
function reversePolish (str) {
let arr = str.split(' ');
for (let i = 0, l = arr.length; i < l; i++) {
if (ops.indexOf(arr[i]) !== -1) {
let expr = arr.splice(i - 2, 3); // start, deleteCount, itemToInsert
arr.splice(i - 2, 0, evalPostfix(expr));
if (arr.length === 1) {
break;
} else {
return reversePolish(arr.join(' '));
}
}
}
// if we reach the end then we're done
return arr[0];
}
console.log(reversePolish(s));
// --------------------------------------------------------------------------------
function reversePolish2(str) {
const dict = {
'+': (a, b) => a + b,
'-': (a, b) => a - b,
'*': (a, b) => a * b,
'/': (a, b) => a / b
};
let stack = [];
str.split(/\s+/).forEach(ch => {
if (Object.keys(dict).includes(ch)) {
let [arg2, arg1] = [stack.pop(), stack.pop()];
stack.push(dict[ch](parseFloat(arg1, 10), parseFloat(arg2, 10)));
} else {
stack.push(ch);
}
});
return stack[0];
}
function assert(a, b) {
let res = (a === b) ? 'pass!' : `fail: ${a} !== ${b}`;
console.log(res);
}
assert(reversePolish2('-4 5 +'), 1);
assert(reversePolish2('5 2 /'), 2.5);
assert(reversePolish2('5 2.5 /'), 2);
assert(reversePolish2('4 2 5 * +'), 14);
assert(reversePolish2('5 1 2 + 4 * 3 - +'), 14);
assert(reversePolish2('4 2 5 * + 1 3 2 * + /'), 2);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment