let my={} function operationsMain(){let version='0.75';my.wd=480 my.opts={q:'(2+3)^4'} let s="";s+='
';s+=popHTML();s+=wrap('user','','rel','text-align: center; margin: 12px;',` `) s+=wrap('tree','','rel','text-align: center;',` `) s+=wrap('answer','output','rel','font: 17px Arial; text-align: center;','') s+='';s+='';s+='

 

';s+='
© 2021 MathsIsFun.com v'+version+'
';s+='
';document.write(s);my.cans=[] canvasInit('canInfo',my.canvasWd,my.canvasHt,2) document.getElementById('question').value=optGet('q') my.parser=new Parser();let inStr=getQueryVariable('i');if(inStr){inStr=decodeURIComponent(inStr);document.getElementById('question').value=inStr;} my.treeQ=false;this.radQ=true;go();} function wrap(id,classStr,type='rel',styleExtra='',middle=''){let s='' s+='\n0)s+=' id="'+id+'"' if(classStr.length>0)s+=' class="'+classStr+'"' if(type=='rel'){s+=' style="position:relative; '+styleExtra+'"'} s+='>' s+=middle s+='\n' return s} function canvasInit(id,wd,ht,ratio){let el=document.getElementById(id);el.width=wd*ratio;el.style.width=wd+"px";el.height=ht*ratio;el.style.height=ht+"px";let g=el.getContext("2d");g.setTransform(ratio,0,0,ratio,0,0);my.cans[id]={el:el,g:g,ratio:ratio}} function go(){let div=document.getElementById('question');let s=div.value;optSet('q',s) s=s.substr(0,1000);s=fixParentheses(s);my.parser.radiansQ=this.radQ;my.parser.newParse(s);div=document.getElementById('answer');let tree=document.getElementById('tree');let g=my.cans.canInfo.g g.clearRect(0,0,g.canvas.width,g.canvas.height) if(my.treeQ){div.style.display='none' tree.style.display='block' nodesDraw();}else{div.style.display='block' tree.style.display='none' div.innerHTML=getSolution();}} function fixParentheses(s){let sttParCount=0;let endParCount=0;for(let i=0;i";s+=my.parser.rootNode.walkFmt();} return(s);} function nodesDraw(){my.tree={xmax:0,ymax:0,lvls:[]} let levels=my.parser.rootNode.getLevelsHigh();this.levelXs=[];for(let i=0;i0){let xSum=0 for(let i=0;i '+s);this.rootNode=this.parse(s);} fixxy(s){s=s.replace(/x[y]/g,'x*y');s=s.replace(/([0-9a])x/g,'$1*x');return s;} fixParentheses(s){let sttParCount=0;let endParCount=0;for(let i=0;i="0"&&c<="9"){thisType="N";}else{if(this.operators.indexOf(c)>=0){if(c=="-"){thisType="-";}else{thisType="O";}}else{if(c=="."||c==this.Variable){thisType="N";}else{thisType="C";}} if(c=="("){thisType="(";} if(c==")"){thisType=")";}} x+=thisType;if(prevType=="("&&thisType=="-"){y+="0";} if(OpenQ){switch(thisType){case "N":break;default:y+=")";OpenQ=false;}} if(prevType=="O"&&thisType=="-"){y+="(0";OpenQ=true;} y+=c;prevType=thisType;} if(OpenQ){y+=")";OpenQ=false;} return(y);} fixImplicitMultply(s){let x=s+"\n";let y="";let prevType="?";let prevName="";let thisType="?";let thisName="";for(let i=0;i="0"&&c<="9"){thisType="N";}else{if(this.operators.indexOf(c)>=0){thisType="O";thisName="";}else{thisType="C";thisName+=c;} if(c=="("){thisType="(";} if(c==")"){thisType=")";}} x+=thisType;if(prevType=="N"&&thisType=="C"){y+="*";thisName="";} if(prevType=="N"&&thisType=="("){y+="*";} if(prevType==")"&&thisType=="("){y+="*";} if(thisType=="("){switch(prevName){case "i":case "pi":case "e":case "a":case this.Variable:y+="*";break;}} y+=c;prevType=thisType;prevName=thisName;} return(y);} reset(){this.tempNode=[];this.errMsg="";} parse(s){if(s==""){return new MathNode("real","0",this.radiansQ);} if(isNumeric(s)){return new MathNode("real",s,this.radiansQ);} if(s.charAt(0)=="$"){if(isNumeric(s.substr(1))){return this.tempNode[Number(s.substr(1))];}} let sLo=s.toLowerCase();if(sLo.length==1){if(sLo>="a"&&sLo<="z"){return new MathNode("var",sLo,this.radiansQ);}} switch(sLo){case "pi":return new MathNode("var",sLo,this.radiansQ);} let bracStt=s.lastIndexOf("(");if(bracStt>-1){let bracEnd=s.indexOf(")",bracStt);if(bracEnd<0){this.errMsg+="Missing ')'\n";return new MathNode("real","0",this.radiansQ);} let isParam=false;if(bracStt==0){isParam=false;}else{let prefix=s.substr(bracStt-1,1);isParam=this.operators.indexOf(prefix)<=-1;} if(!isParam){this.tempNode.push(this.parse(s.substr(bracStt+1,bracEnd-bracStt-1)));return this.parse(s.substr(0,bracStt)+"$"+(this.tempNode.length-1).toString()+s.substr(bracEnd+1,s.length-bracEnd-1));}else{let startM=-1;for(let u=bracStt-1;u>-1;u--){let found=this.operators.indexOf(s.substr(u,1));if(found>-1){startM=u;break;}} let nnew=new MathNode("func",s.substr(startM+1,bracStt-1-startM),this.radiansQ);nnew.addchild(this.parse(s.substr(bracStt+1,bracEnd-bracStt-1)));this.tempNode.push(nnew);return this.parse(s.substr(0,startM+1)+"$"+(this.tempNode.length-1).toString()+s.substr(bracEnd+1,s.length-bracEnd-1));}} let k;let k1=s.lastIndexOf("+");let k2=s.lastIndexOf("-");if(k1>-1||k2>-1){if(k1>k2){k=k1;let nnew=new MathNode("op","add",this.radiansQ);nnew.addchild(this.parse(s.substr(0,k)));nnew.addchild(this.parse(s.substr(k+1,s.length-k-1)));return nnew;}else{k=k2;let nnew=new MathNode("op","sub",this.radiansQ);nnew.addchild(this.parse(s.substr(0,k)));nnew.addchild(this.parse(s.substr(k+1,s.length-k-1)));return nnew;}} k1=s.lastIndexOf("*");k2=s.lastIndexOf("../index.html");if(k1>-1||k2>-1){if(k1>k2){k=k1;let nnew=new MathNode("op","mult",this.radiansQ);nnew.addchild(this.parse(s.substr(0,k)));nnew.addchild(this.parse(s.substr(k+1,s.length-k-1)));return nnew;}else{k=k2;let nnew=new MathNode("op","div",this.radiansQ);nnew.addchild(this.parse(s.substr(0,k)));nnew.addchild(this.parse(s.substr(k+1,s.length-k-1)));return nnew;}} k=s.indexOf("^");if(k>-1){let nnew=new MathNode("op","pow",this.radiansQ);nnew.addchild(this.parse(s.substr(0,k)));nnew.addchild(this.parse(s.substr(k+1,s.length-k-1)));return nnew;} if(isNumeric(s)){return new MathNode("real",s,this.radiansQ);}else{if(s.length==0){return new MathNode("real","0",this.radiansQ);}else{this.errMsg+="'"+s+"' is not a number.\n";return new MathNode("real","0",this.radiansQ);}}}} class MathNode{constructor(typ,val,radQ){this.tREAL=0;this.tlet=1;this.tOP=2;this.tFUNC=3;this.radiansQ=true;this.setNew(typ,val,radQ);} setNew(typ,val,radQ){this.radiansQ=typeof radQ!=='undefined'?radQ:true;this.clear();switch(typ){case "real":this.typ=this.tREAL;this.r=Number(val);break;case "var":this.typ=this.tVAR;this.v=val;break;case "op":this.typ=this.tOP;this.op=val;break;case "func":this.typ=this.tFUNC;this.op=val;break;} return(this);} clear(){this.r=1;this.v="";this.op="";this.child=[];this.childCount=0;} addchild(n){this.child.push(n);this.childCount++;return(this.child[this.child.length-1]);} getLevelsHigh(){let lvl=0;for(let i=0;i0){let parq=false;if(this.op=="add") parq=true;if(this.op=="sub") parq=true;if(prevop=="div") parq=true;if(noparq) parq=false;if(this.typ==this.tFUNC) parq=true;if(this.typ==this.tOP){}else{s+=this.fmt(true);} if(parq) s+="(";for(let i=0;i0) s+=this.fmt();s+=this.child[i].walkFmta(false,this.op);if(this.typ==this.tFUNC||(parq&&i>0)){s+=")";}}}else{s+=this.fmt();if(prevop=="sin"||prevop=="cos"||prevop=="tan"){if(this.radiansQ){s+=" rad";}else{s+="°";}}} return s;} walkNodesFmt(level){let s="";for(let i=0;i2){f*=i;} return f;} function isNumeric(n){return!isNaN(parseFloat(n))&&isFinite(n);} function getQueryVariable(variable){let query=window.location.search.substring(1);let vars=query.split("&");for(let i=0;i