JSFiddle - React, Tailwind, and code Playground
JavaScript
function rnd(){
return Math.random();
}
function round(n){
return Math.round(n);
}
String.prototype.lastCharAt=function(position){
return this.charAt(this.length-1-position);
}
Number.prototype.power=function(pwr){
return Math.pow(this, pwr);
}
var minimo, alReves, union, partes, cual, rand, numeros, intervalos, num, i, j, resta, txt, intg, oper;
minimo=(10).power(-16);
alReves = {
'(' : ']',
')' : '[',
'[' : ')',
']' : '('
};
function random(str){
union = /u/i;
rand=rnd();
numeros=[];
if(/[\^u]/i.test(str)){ // varios intervalos
if(union.test(str)){ // unión de intervalos
partes=str.split(union); // separamos por el 'operador'
cual = rand>=(1-minimo)/partes.length?1:0; // decidimos en qué intervalo estará nuestro número
numeros=partes[cual].match(/\d+/g); // cogemos los números que haya en ese intervalo
resta=numeros[1]-numeros[0]; // restamos el menor al mayor
//alert('rand:'+rand+'\ncual:'+cual+'\nbool:'+bool+'\npartes:'+partes.join()+'\nnumeros:'+numeros.join()+'\nresta:'+resta);
rand*=resta; // multiplicamos por la diferencia
rand+=parseFloat(numeros[0]); // sumamos el menor
//alert(rand);
if(rnd()>=(1-minimo)/partes.length) rand+=(cual?-1:1)*resta/2; // para que puedan darse todos los números
if(partes[cual].charAt(0)=='('&&round(rand)==numeros[0]) rand+=0.5; // si es abierto por la izquierda, evitamos que se redondee "mal"
if(partes[cual].lastCharAt(0)==')'&&round(rand)==numeros[1]) rand-=0.5; // si es abierto por la derecha, evitamos que se redondee "mal"
//alert(rand);
}else{
if(/\^/.test(str)){ // diferencia simétrica de conjuntos
var txt='', intg=str.match(/\d+/g), oper=str.match(/[\[\]()]/g); // [ ó ] ó ( ó )
txt+=oper[0]+intg[0]+','+intg[2]+alReves[oper[2]]+'U'+alReves[oper[3]]+intg[3]+','+intg[1]+oper[1];
// colocamos los elementos de los arrays de los match() según convenga
return new random(txt); // devolvemos un new random que cambiará la diferencia simétrica (^) por unión...