numero aleatorio

LioNHearT

buenas noches.

alguien sabe como puedo generar un numero int aleatorio de 4 cifras, las cuales sean todas ellas diferentes?

osea generar un int del tipo 1234, 4567, 4289,...

es que nose si hay alguna funcion o algo, porque sino es un follon hacerlo...

gracias!

NeO_PedritO

Se me ocurre que uses un vector de 4 campos y en cada uno generes el numero aleatorio entre 0 y 9.
Luego compruebas que sean todos distintos entre si, y si no vuelves a generar el que se repita y asi.

Si existe alguna funcion especifica para hacer eso lo desconozco xD

LioNHearT

el problema está en que no upedo usar un vector, osea a partir de la funcion rand%10000 genere un numero aleatorio entre 0000 y 9999, pero lo que quiero es que sea de 4 cifras diferentes.

se os ocurre algo?

Deoxys

Function aleatorio (var vector):integer

var i,j:integer;

begin
randomize
aleatorio:=0
while aleatorio=0 do

begin
i:=1
for i:=1 to 4 do

begin
vector.i:=random (9)
j:=i-1
if vector.i = vector.j do (i:=i-1)
end;
aleatorio:=vector
end;

otra opción que se me ocurre es

for i:=1 to 4 write (random (9))

perdon si he puesto alguna burrada :)

r2d2rigo

#4, nada de vectores

numero = (rand()%10)1000 + (rand()%10)100 + (rand()%10)*10 + (rand()%10);

Vas apuntando los resultados del rand() en variables temporales y si alguno ya ha salido, buscas otro.

NeO_PedritO

Por que no puedes usar un vector?

Si lo que quieres es usarlo como un entero, puedes convertirlo sin problema. Por ejemplo:

1|2|3|4 = 11000+2100+310+41

EDIT: coño #5 xDDD pero es verdad, puedes usar tambien variables auxiliares y fuera.

MaKi

dado este string = "0123456789"

  • 1 coges una posicion aleatoria
  • memerizas el número de la posicion
  • borras le letra de esa posición
  • Vuelta empezar 4 veces
MaKi

Pongo una función que hice para la uni en pascal, que la idea es más o menos lo mismo, pero en lugar de numeros sin repetir, un tablero sin repetir.

      function crearTablero():Ttableros;

  {********************************************************}

  var

     valores_posibles:string;

     aux:Ttableros;

     aleatorio:integer;

     f,c:char;



     function getProx_idTablero():integer;

     begin

        getProx_idTablero := filesize(fT);

     end;



  begin

     Randomize;

     aux.idTablero := getProx_idTablero();

     valores_posibles := 'abcdefghijklmnopqrstuvwxyz 0123456789().,¡!¿?';



     for f:='a' to 'e' do

        for c:='0' to '8' do

           begin

           aleatorio := random(length(valores_posibles))+1;

           aux.tablero[f,c] := valores_posibles[aleatorio];

           delete(valores_posibles,aleatorio,1)

           end;

     write(fT , aux);

     crearTablero := aux;

  end;
elkaoD
int aleat4()
{
    char num_list[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int num_size = 9; // Tamaño del vector num_list

int numero=0;

int i;
for (i=1; i<=1000; i*=10)
{
  int aleatorio = rand()%(num_size+1);
  numero += num_list[aleatorio] * i;
  num_list[aleatorio] = num_list[num_size];
  num_size--;
}

return numero;
}
NeB1

lo más eficiente es lo de #8 que te hace lo mismo sin apenas gastar rands, además es una forma bastante ocurrente

B

#1 Olvídalo... los números aleatorios no existen.

elkaoD

#10 y mi código no lo alabas con lo bonito y optimizado que está? :(

NeO_PedritO

#12 Celoso? xDD

Esta muy cuco ;) xD

LOc0

#9 Qué bien me habrías venido de compi en algunas prácticas de la uni...

Por cierto, lo de #8 está muy bien, pero en la biblioteca estándar de C no hay una función que te borre un elemento de un array y te desplace todos hacia arriba, así que me quedo con #9 (además que eso de copiar el último elemento en la posición recién usada para que si vuelve a salir el mismo número no se repita me ha molado).

#11

Quitando que Einstein llevara razón y no exista un Dios que juegue a los dados, SÍ es posible generar números aleatorios, aunque como todo en esta vida no es 100% gratis -> http://www.random.org/

Salu2 ;)

PD:

Respuesta corta: con una función matemática (retroalimentada) R(x) donde X es un número que se le pasa al principio para "arrancar" el motor (se llama semilla y vale cualquier cosa, pero a igual semilla, igual secuencia generada). La gracia está en que para un periodo determinado, la distribución de los números generados es uniforme (o casi casi), pero a partir de usarla un cierto número de veces se empiezan a repetir patrones y por tanto los números generados dejan de ser aleatorios. (Joder con la respuesta corta xD).
||
||
\/

ItNaS

cuna pregunta chorra, como genera un ordenador numeros aleatorios?

NeO_PedritO

A lo de #14 añadir que se suele usar la hora actual para generar la semilla, por ejemplo.

dagavi

#15 como te contesta #14, pero aun más corto: el ordenador no genera números aleatorios.
Básicamente lo puedes ver como una función que dado un número genera otro a partir de una operación matemática.
Es por eso que al usarse operaciones de números aleatorios se suele inicializar con un valor que pueda ser diferente en 2 ejecuciones, normalmente se suele usar alguna función time() ya que entre 2 ejecuciones consecutivas es muy probable que cambie su valor.

Poisonous

funcion aleajactaest (dimension)

JuAn4k4

#12 puede salirte dos 9's seguidos al principio y tu numero acaba en 99

[irony]

usados[ 0...9] = 0;
int more_lives= 5;
int rellenados = 1;

aux = rand(999999);

numero = aux % 10;
aux = aux - numero;
usados[numero] = 1;
goto aver;

puesno:
more_lives = 6;
aux = rand(999999);

aver:
if ( rellenados == 4 ) goto MeEncantanLosGOTOS;

if (! more_lives) goto puesno;
aux = (aux / 10);
este = aux % 10;
more_lives --;
if !( usados[este] ){ numero = numero*10 + este; rellenados++;}
else goto aver;

MeEncantanLosGOTOS:

[/irony]

0buS

hacer los rands seguidos 4 veces para 4 cifras no tiene sentido, porque no va a salir "aleatorio". El rand va por el tiempo del pc, y si la linea la lee casi al mismo tiempo, la mayoria de veces saldran los mismos numeros.

#9 no puede usar arrays xd.

elkaoD

#19 si te sale un 9 al principio, el 9 se cambia por el 9 (Se queda igual) y se elimina la última opción (La 9) así que no puede salir otro 9 seguido. Eso en teoría xD Voy a echarle un vistazo en el debugger a ver si la he cagado en algo, que es probable.

(Supongo que se ha notado que #12 iba de coña y tal.)

#20 oh mierda tienes razón xD (Con lo de los arrays.)

Soleil

una solución en Scheme...
funciona de manera recursiva añadiendo un elemento aleatorio
mientras la longitud de la lista (filtrada para tener elementos únicos)
sea menor de 4

(define (random-4 ls)
  (if (= 4 (length (uniq ls))) ls
  (random-4 (cons (rand 9) ls))))

(sí, como siempre... me aburro)
PD: dependiendo de la implementación, "uniq" puede llamarse
"remove-duplicates".

Edit...
Otra solución que únicamente hace 4 rands, manteniendo una lista
con los números posibles donde escoger.

(let loop ((numbers (iota 10)) (result '()))
  (if (< 4 (length result))
    (begin
      (set! result (cons (choose numbers) result))
      (remove! numbers (car result))
      (loop numbers result))
    result))
JuAn4k4

#21 numsize vale 9 y haces random de 9+1 , esto no es hasta 10 ? y luego bajas numsize a 8 -> random hasta el 9, puede salir otro 9, ¿no?

#20 Error, el rand no va por tiempo, la semilla se suele cojer por tiempo.

#24 Ok entonces no puede salir 99. Y el codigo ese funciona ^, hice una practica de la universidad asi y no me dijeron nada, solo por confirmar que no se miran el codigo.

elkaoD

rand()%10 da un numero de 0 a 9, no hasta 10. Por cierto, me muero con tu código con tanto goto xD

MaKi

puf xDD

Para el autor del post: deberías dejar bien claro en el post inicial, el lenguaje y las restricciones del problema, ya que es fácil salirse del lenguaje (yo con pascal ...) o directamente irse al paradigma funcional xDD

#14 efectivamente en c no se pueden borrar elementos, ni en c, ni en ningún lenaguaje, ya que en la propia definición de array esta restringuido esa posibilidad. Mi ejemplo es un string en pascal. Los string de pascal son listas de "char".

Habría que implementar algo parecido en C, eso puede complicar el problema si no lo has hecho nunca, por tanto opta por otras soluciones más costosas tiempo-memoria pero más fáciles de implementar.

LioNHearT

#25 cierto, pido disculpas xD

weno el lenguaje es C++.

creo que ya lo he hecho, no es la forma mas eficiente pero me sirve. la idea es que calculo un numero aleatorio de 4 cifras y mediante % creo 4 variables, 1 con cada digito del numero. entonces fuerzo un bucle en el que, hasta que las 4 no sean diferentes, no salga. vendrias a ser asi (falta terminar el if, porque solo miro que sean diferentes las millares, faltaria poner los otros 3 numeros, pero esa es la idea).

int  aleatori (int x){
     int un,dec,cent,mil;
     bool genera=false;
     while(!genera){
     srand(time(NULL));
     x=rand()%10000;
     un=x%10;
     dec=(x/10)%10;
     cent=((x/10)/10)%10;
     mil=(((x/10)/10)/10)%10;
if(un!=dec && un!=cent && un!=mil)genera=true;
     }
    return x;
     }

como lo veis? se que no es lo mas eficiente, pero en principio genera un numero aleatorio xD

edit: solo tengo un problemin. me genera diferentes numeros cada vez que voy a la funcion, pero si hago un for para hacer 4 veces 4 numeros, me salen 4 numeros iguales (pero con 4 digitos diferentes). como lo puedo arreglar?

LOc0

La llamada a srand() antes del bucle.

Explicación:

srand() cambia la secuencia aleatoria siempre que la llames con semillas distintas pero como usas de semilla time(NULL) (que sólo cambia cada segundo), si llamas antes a srand() en vez de cambiar la secuencia te la reinicia.

Salu2 ;)

PD: Es ineficiente de cojones xD pero así empezamos el 99% de los mortales. La cosa es que es TUYO ;).

LioNHearT

jajaja. se ke no es eficiente, y la verdad que ya no soy un novatillo :$. pero que en esta parte del curso no me piden eficiencia y me estoy comiendo yo todo el proyecto, asi que,... suficiente xDD

JuAn4k4

x/10 /10 /10 ??? Dios... x/1000 que tal funciona ? xD

Te das cuenta que, de la forma en la que lo haces no saldras del bucle hasta que las 4 cifras sean diferentes sacando las 4 cifras en el mismo rand() ?

1120 y luego 3988 sacarias 6 cifras diferentes 123980 , pero tu bucle volveria a empezar.

Probabilidad de que en 4 cifras 2 se repitan.

LioNHearT

weno si, entre 1000 hara lo mismo, pero bueno es para ke lo entendais. si tampoko he puesto toda la condicion del if xD.
lo ke tu dices kreo k no funciona. mi programa lo unico que hara es comparar 4 cifras entre ellas, y si son diferentes retornara el numero. es decir:

1134= 1 1 3 4. no son todas diferentes por lo tanto no retorna el numero.

1234= 1 2 3 4. 4 cifras diferentes por lo tanto retornara 1234 (return x)

weno os pongo como lo he dejado al final, asi nos aclaramos todos xD:

    int un,dec,cent,mil, x;
     bool genera=false;
     srand(time(NULL));
     while(!genera){
     x=rand()%10000;
     un=x%10;
     dec=(x/10)%10;
     cent=(x/100)%10;
     mil=(x/1000)%10;
     if((un!=dec && un!=cent && un!=mil) &&
     (dec!=un && dec!=cent && dec!=mil) &&
     (cent!=un && cent!=dec && cent!=mil) &&
     (mil!=un && mil!=dec && mil!=cent))
     genera=true;
     }
    return x;