Enero 15, 2011, 06:51:28 PM Ultima modificación: Enero 15, 2011, 07:02:51 PM por Fenris78
Nombre del creador:

Fenris78

Breve descripci?n de su funci?n:

Devuelve una lista de n valores enteros aleatorios, escogidos del 1 al vmaximo sin repeticion. El ID de la lista se puede usar despues para acceder a cualquiera de sus valores.

Ej: milista=scliale(10,30);

Versi?n GM utilizada:  

:GM8:

C?digo del Script:

[gml]
//sc_liale(nvalores,vmaximo);  Ej: milista=scliale(10,30);

var lista,ntotal,nmax,nvalido,numero;

lista=ds_list_create(); //Creo una lista
ntotal=0; nvalores=argument0; nmax=argument1; nvalido=false;

for(i=1;ntotal<nvalores;i+=1)
{
   numero=irandom(nmax)+1;
   for(i=1; i<nvalores; i+=1){ if(ds_list_find_value(lista,i)=numero){ nvalido=false; } else { nvalido=true; } } //verifico si esta seleccionado
   if(nvalido=true) { ntotal+=1; ds_list_add(lista,numero); }
}
return lista; //Devuelvo su ID[/gml]

#1 Enero 17, 2011, 05:51:58 PM Ultima modificación: Enero 17, 2011, 10:13:30 PM por PoSvA
Tambi?n puedes usar un while en vez de 2 bucles for:
[gml]
var l,i,str,value;
l=ds_list_create();
i=0;
str="|";

while (i<argument0)
{
   value=irandom_range(0,argument1);
   if (string_count("|"+string(value)+"|",str)<=0)
   {
       i+=1;
       str+=string(value)+"|";
       ds_list_add(l,value);
   }
}

return l;
[/gml]

No lo he testeado, ni s? si es m?s optimizado, pero siempre est? bien tener otra opini?n! :D
Por cierto no conoc?a la funci?n irandom, gracias por ense??rmela xD

Aha, pero si yo por ejemplo ya agregu? el 10 en random y luego toca el 1 dar? como que el 1 ya est? seleccionado por estar dentro del 10, deber?as inicializar el str="|" y chequear asi
[gml]if (string_count("|"+string(value)+"|",str)<=0)[/gml]





Solo agregaria que se utilice un break una vez que se haya encontrado el valor como invalido para no tener que revisar el resto de valores pues ya no es necesario, y asi nos ahorramos algo de tiempo.Con listas mas grandes este ahorro sera mas evidente :D
"Si he llegado a ver más lejos que otros, es porque me subí a hombros de gigantes"  Isaac Newton

Hola, tambien puedes usar 2 listas y hace el proceso mas simple, principalmente cuando son numeros muy grandes (por la tasa de rechazo), hice un ejemplo (adjunto)...
Saludos Cordiales!!!

Para este tipo de cosas creo que lo mejor es usar una cola de prioridad, meter los valores en orden y asignarles una prioridad aleatoria, as? te ahorras anidar los dos bucles y el script ser? m?s r?pido:

[gml]var priO, lstD, iN, maxN, maxV;
maxN = argument0;//N?mero de elementos
maxV = argument1;//Valor m?ximo
priO = ds_priority_create();
lstD = ds_list_create();

for (iN=0; iN<=maxV; iN+=1) ds_priority_add(priO, iN, random(maxV));//A?ado los valores en orden pero con prioridad aleatoria
repeat (maxN) ds_list_add(lstD, ds_priority_delete_max(priO));//Voy cogiendo los valores finales seg?n la prioridad

return lstD;[/gml]

Tambi?n podr?a hacerse con dos listas y la funci?n ds_list_shuffle:
[gml]var lstO, lstD, iN, maxN, maxV;
maxN = argument0;//N?mero de elementos
maxV = argument1;//Valor m?ximo
lstO = ds_list_create();
lstD = ds_list_create();

for (iN=0; iN<=maxV; iN+=1) ds_list_add(lstO, iN);//A?ado los valores en orden
ds_list_shuffle(lstO);//Desordeno la lista
for (iN=0; iN<maxN; iN+=1) ds_list_add(lstD, ds_list_find_value(lstO, iN));

return lstD;[/gml]
Este caso ser? un pel?n m?s lento que con las colas de prioridad pues necesitamos dos bucles for en lugar un for y un repeat.

Que util es este Script!!!  :D Muchiiiisimas gracias, me funciono de maravilla...