Skip to content

Instantly share code, notes, and snippets.

@YarGnawh
Last active February 17, 2017 05:06
Show Gist options
  • Save YarGnawh/710fb76a269b25a6e4ad5dd72be9fb15 to your computer and use it in GitHub Desktop.
Save YarGnawh/710fb76a269b25a6e4ad5dd72be9fb15 to your computer and use it in GitHub Desktop.
Equation Solver using Map/Reduce
function parse(eq) {
var nest = 0;
eq = eq.reduce(function(acc, val) {
if (val == '(') {
nest++;
} else if (val == ')') {
nest--;
}
if (val == '(' && nest == 1) {
acc.push([])
} else if (val == ')' && nest == 0) {
acc[acc.length - 1] = parse(acc[acc.length - 1]);
} else if (nest > 0) {
acc[acc.length - 1].push(val);
} else {
if (isNaN(val)) {
acc.push(val)
} else {
acc.push(Number(val));
}
}
return acc;
}, []);
return eq;
}
function solve(eq) {
var op = null;
eq = eq.reduce(function(acc, val) {
if (Array.isArray(val)) {
val = solve(val);
}
acc.push(val);
return acc;
}, []);
['^', ['*', 'x', '/', '÷'], ['+', '-']].map(function(op) {
var calc = null;
eq = eq.reduce(function(acc, val) {
if (calc) {
switch(calc) {
case '^': acc[acc.length - 1] = Math.pow(acc[acc.length - 1], val); break;
case 'x': case '*': acc[acc.length - 1] *= val; break;
case '÷': case '/': acc[acc.length - 1] /= val; break;
case '+': acc[acc.length - 1] += val; break;
case '-': acc[acc.length - 1] -= val; break;
}
calc = null;
} else if ((Array.isArray(op) && op.indexOf(val) != -1) || op == val) {
calc = val;
} else {
acc.push(val);
}
return acc;
}, []);
});
return eq[0];
}
[
[1, '+', 2, '*', 3, '+', 4, '*', 5, '+', 6], // 1 + 2 * 3 + 4 * 5 + 6 = 33
['(', '(', 2, '+', 3, ')', '^', '2', ')', '*', 1.5], // ( ( 2 + 3 ) ^ 2 ) * 1.5 = 37.5
[6, '+', 5, '-', 4, '*', 3, '/', 2, '^', '(', 1, '+', 0, ')'], // 6 + 5 - 4 * 3 / 2 ^ ( 1 + 0 ) = 5
['(', '(', 6, '+', 4, ')', '*' ,'(', 3, '-', 1, ')', ')', '/', 5] // ( ( 6 + 4 ) * ( 3 - 1 ) ) / 5 = 4
].map(function(t) {
console.log(t.join(' '), '=', solve(parse(t)));
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment