require("string","cas","table") function ucln(a,b) if(b%a==0) then return a else return ucln(b%a,a) end end function del1(a) if(a==1) then return "" else return a end end function duavedangcoban(s) i=1 s=string.gsub(s,"%+","%)%+%(") s="val_1*("..s s=string.gsub(s,"%+",function (s) i=i+1 return "+val_"..i.."*" end) s=string.gsub(s,"%=","%)%=%(") s=string.gsub(s,"%=",function (s) i=i+1 return "=val_"..i.."*" end) s=string.gsub(s,"(%u)([0-9])","%1*%2") s=string.gsub(s,"(%u+%l)([0-9])","%1*%2") s=string.gsub(s,"(%u)","+%1") s=string.gsub(s,"%(","+%1") s=string.gsub(s,"%(%+","%(") s=string.gsub(s,",%+",",") s=string.gsub(s,"(%))([0-9])","%1*%2") s=string.gsub(s,",%*%+","%*") s=tostring(cas.expand(s)) return s,i end function getval(sf) local val,s,i={},sf,1 for w in string.gmatch(s,"%u%l") do val[i]=w s=string.gsub(s,val[i],"") i=i+1 end for w in string.gmatch(s,"%u") do val[i]=w i=i+1 end i=1 table.sort(val) while(i<#val) do if(val[i]==val[i+1]) then table.remove(val,i) else i=i+1 end end return(val) end function canbang(ss) s,numval=duavedangcoban(ss) gv=getval(s) strgv="|"..table.concat(gv,"=0|").."=0" func="solve({" for i=1,#gv,1 do func=func..cas(s.."|"..tostring(gv[i]).."=1"..strgv) if i~=#gv then func=func.."," else func=func.."}," end end func=func.."{" for i=1,#gv,1 do func=func.."val_"..i if i~=#gv then func=func.."," else func=func.."})" end end if(#gv<numval) then for i=#gv+1,numval,1 do func=func.."|val_"..i.."=87297210" end end func=string.gsub(func,"=0","=87297210") kq=tostring(cas.getright(func)) dostring("skq="..kq) uc=del1(skq[1]) for i=2,#skq,1 do uc=ucln(uc,skq[i]) end ss=string.gsub(ss,"0","??") ss=string.gsub(ss,"1","??") ss=string.gsub(ss,"2","??") ss=string.gsub(ss,"3","??") ss=string.gsub(ss,"4","??") ss=string.gsub(ss,"5","??") ss=string.gsub(ss,"6","??") ss=string.gsub(ss,"7","??") ss=string.gsub(ss,"8","?_") ss=string.gsub(ss,"9","??") i=1 ss=skq[1]/uc..ss ss=string.gsub(ss,"%+",function (s) i=i+1 if (i>#skq) then return "+"..del1(87297210/uc) else return "+"..del1(skq[i]/uc) end end ) ss=string.gsub(ss,"%=",function (s) i=i+1 if (i>#skq) then return "="..del1(87297210/uc) else return "="..del1(skq[i]/uc) end end ) return(ss) end export{balace=canbang}
Usage: balace(string)
some example:
--It may be any name, base on your choice
require "balace"
print(balace("H2+O2=H2O")) ------------------> "2H2+O2=2H2O"
--It may be any name, base on your choice
require "balace"
print(balace( " H2+Ca(CN)2+NaAlF4+FeSO4+MgSiO3+KI+H3PO4+PbCrO4+BrCl+CF2Cl2+SO2=PbBr2+CrCl3+MgCO3
+KAl(OH)4+Fe(SCN)3+PI3+NaSiO3+CaF2+H2O")) ------------------> (Try it yourself , it's a great equation)