You are not recognized as the original poster of this topic.
let mod=(n,m)=>(n%m+m)%m,
oper={
"+":(a,b)=>a+b,"-":(a,b)=>a-b,
"*":(a,b)=>a*b,"/":(a,b)=>a/b,
"%":mod,"**":(a,b)=>a**b
},fun={ //.length for N of arguments
sin:Math.sin,rand:Math.random,
abs:Math.abs,floor:Math.floor
},chooseRand=a=>a[Math.floor(Math.random()*a.length)];
/*
Examples of Reverse Polish Notation (RPN):
t 220 * 1 % → (t*220)%1
rand 1 t 1 % - 5 ** * → rand()*((1-(t%1))**5)
.5 1 10 t * 2 % - abs - → .5-abs(1-((10*t)%2))
*/
function genExpr(){
const ops=Object.keys(oper),
unaries=Object.keys(fun).filter(k=>fun[k].length===1),
terminals=["t",...Object.keys(fun).filter(k=>fun[k].length===0)];
let stack=[],esd=0,maxLen=10; //eval stack depth
while(esd<1||Math.random()>.2||stack.length<3){
let options=["terminal"];
if(esd>=1)options.push("unary");
if(esd>=2)options.push("binary");
const choice=chooseRand(options);
switch(choice){
case"terminal":
if(Math.random()<.2){
stack.push(chooseRand(terminals));
}else{
stack.push(floor(random()*21)*.5-5);
}
esd++;
break;
case"unary":
stack.push(chooseRand(unaries));
break;
case"binary":
stack.push(chooseRand(ops));
esd--;
break;
}
if(stack.length>=maxLen)break;
}
//ensure minimum size and balance
while(esd!==1||stack.length<3){
if(esd<1){
stack.push(chooseRand([.5,1])); //push dummy operand
esd++;
}else if(esd>1){
stack.push("+"); //try to reduce stack
esd--;
}else{break;}
}
return stack;
}
function evalExpr(stack){
return function(tVal){
let s=[];
for(let token of stack){
try{
if(typeof token==="number"){
s.push(token);
}else if(token==="t"){
s.push(tVal);
}else if(oper.hasOwnProperty(token)){
if(s.length<2)return 0; //not enough
const b=s.pop(),a=s.pop(),
result=oper[token](a,b);
s.push(isFinite(result)?result:0);
}else if(fun.hasOwnProperty(token)){
if(fun[token].length===0){s.push(fun[token]());continue;} //e.g. rand
if(!s.length)return 0; //no args to push
const result=fun[token](s.pop()); //TODO: multiple args
s.push(isFinite(result)?result:0);
}else{return 0;}
}catch(e){
console.error("Eval error:",e,"at",token);
return 0;
}
}
const result=s.pop()||0;
return isNaN(result)||!isFinite(result)?0:result;
};
}
/*let timer={
t:0,l:.1
},expr=genExpr(),eFun=evalExpr(expr);
return(t,SR)=>{
timer.t+=1/SR;
if(timer.t>=timer.l){
timer.t%=timer.l;
expr=genExpr();eFun=evalExpr(expr);
}
return eFun(t);
};*/
let split=str=>str.split(" ").map(e=>{let n=parseFloat(e);return isNaN(n)?e:n;}),
eFun=[
evalExpr(split(".5 1 440 t * 2 % - abs -")),
evalExpr(split("rand .5 - 1 t 1 % - 5 ** *")),
...(new Array(5).fill(0).map(()=>evalExpr(genExpr())))
];
return t=>{
return eFun[floor(t/2)%eFun.length](t);
};