JSFiddle - React, Tailwind, and code Playground
HTML
<form action="#">
<input type="text" name="formula" value="1+3*(5-1)"/>
<input type="submit"/>
</form>
<hr/>
<div id="junk"></div>
JavaScript
var evaluate={
'+':(a,b)=>a+b,
'-':(a,b)=>a-b,
'*':(a,b)=>a*b,
'/':(a,b)=>{b==0?null:a/b}
}
var operators = Object.keys(evaluate);
//does not touch hand
function go(hand, handSize, goal){
if(handSize ==1){
if(hand[0].v == goal){
console.log('GOAL '+hand[0].toString());
}
return;
}
for(var i = 0; i<hand.length; ++i){
for(var j = i+1; j<hand.length; ++j){
var t = hand.slice(0);
var a = t.splice(i,1)[0];
var b = t.splice(j-1,1)[0];
operators.forEach(op=>{
var v = evaluate[op](a.v,b.v);
if(v!=null){
t[handSize-2] = new Tree(a,b,op,v);
go(t, handSize-1, goal);
}
})
}
}
}
function Tree(a,b,op,v){
this.a = a;
this.b = b;
this.op = op;
this.v = v;
}
Tree.prototype.toString = function(){
var strongNoPar = function(x){
return x.leaf()?x.v:'('+x.toString()+')';
}
var noPar = function(x){
return x.leaf()?x.v:
x.multiplicative()?x.toString():'('+x.toString()+')';
}
if(this.leaf()){
return this.v;
}
if(this.op == '+'){
return this.a.toString()+this.op+this.b.toString();
}
if(this.op == '-'){
return this.a.toString()+this.op+noPar(this.b);
}
return noPar(this.a)+this.op+strongNoPar(this.b);
}
Tree.prototype.leaf = function(){
return !this.a;
}
Tree.prototype.multiplicative = function(){
if(this.leaf()){return true;}
return (this.op=='*' || this.op=='/') && this.a.multiplicative() && this.b.multiplicative();
}
function process(f){//'2+3*5-(1+6*50)'
var goal = eval(f);
var numbers = f.replace(/[()]/g,'').split(/[-+*/]/).map(x=>new Tree(null,null,null,parseFloat(x.trim(), 10)));
var bef = Date.now();
go(numbers, numbers.length, goal)
console.log('goal was '+ goal+ ', elapsed '+ Math.floor(Date.now()-bef)+' ms')
}
var...