Discussion:
Programacion
vascocho
2011-06-02 12:13:04 UTC
Permalink
---------- Mensaje reenviado ----------
De: vascocho <***@gmail.com>
Fecha: 1 de junio de 2011 14:47
Asunto: Re: Programacion de Video Juegos
Para: ArYiXb <***@gmail.com>


Hola gracias por su ayuda aca va mi primer duda en un ejercicio de
progrmacion.

*Actividad a realizar

*Escribir una función que devuelva la tirada de un dado de rol de n caras.
Se contemplan dados que no existirían físicamente como los de 5 caras.

*El Ejercicio resuelto lo adjunte.*

*Repuesta del profesor :*

El ejercicio está bien, no debería colocarse el srand dentro de la función o
no tendrá aleatoriedad

*Duda*:
Donde colocar el srand.

Gracias
Saludos
Andres Morales
2011-06-06 12:23:09 UTC
Permalink
Post by vascocho
---------- Mensaje reenviado ----------
Fecha: 1 de junio de 2011 14:47
Asunto: Re: Programacion de Video Juegos
Hola gracias por su ayuda aca va mi primer duda en un ejercicio de
progrmacion.
*Actividad a realizar
*Escribir una función que devuelva la tirada de un dado de rol de n caras.
Se contemplan dados que no existirían físicamente como los de 5 caras.
*El Ejercicio resuelto lo adjunte.*
*Repuesta del profesor :*
El ejercicio está bien, no debería colocarse el srand dentro de la función o
no tendrá aleatoriedad
Donde colocar el srand.
Gracias
Saludos
Yo no lo considero así, con srand estás generando la semilla del número
aleatorio, y la misma la estás generando en el momento con un time, por lo
tanto es igual de aleatoria la semilla si se encuentra fuera o dentro de la
función. De todas maneras, yo la pondría fuera de la función, al principio
del main(), solo para ser ordenado y también para poder tener n funciones
que generaran números aleatorios distintas sin tener que utilizar srand en
cada una de ellas.
Alejandro Vargas
2011-06-06 12:38:16 UTC
Permalink
Post by Andres Morales
Yo no lo considero así, con srand estás generando la semilla del número
aleatorio, y la misma la estás generando en el momento con un time, por lo
tanto es igual de aleatoria la semilla si se encuentra fuera o dentro de la
función. De todas maneras, yo la pondría fuera de la función, al principio
del main(), solo para ser ordenado y también para poder tener n funciones
que generaran números aleatorios distintas sin tener que utilizar srand en
cada una de ellas.
Yo tendría a estar de acuerdo con el profesor. No es necesario
inicializar el generador de números al azar más de una vez. Hacerlo en
realidad desvirtua el funconamiento del algoritmo.

No es que el número que te salga no sea al azar, sino que es mucho más
predecible.

Tratñandose de algo sencillo como un "dado", puede que no importe pero
como en este caso el ejercicio no se trata de hacer un dado en sí sino
de aprender a programar, es conveniente que el alumno sepa que si bien
en este caso daría más o menos lo mismo, no es conveniente que quede
con la idea de que así está bien, porque algún día podría darse el
caso en que hacer eso suponga una vulnerabilidad en algún sistema.

Si yo se que tu programa inicializa el generador de números al azar
con una marca de tiempo siempre antes de obtener el número, puedo
hacer un programa que pruebe unos cuantos miles de marcas de tiempo
"razonables" y estoy seguro de que alguno de los números que obtenga
será el tuyo.

Claro que después de ver la manera en que la gente de Sony elige
números al azar, este programa es un lujo.

Loading Image...




--
Qapla'
Alejandro Vargas
v***@lugmen.org.ar
2011-06-06 13:27:38 UTC
Permalink
Post by vascocho
Hola gracias por su ayuda aca va mi primer duda en un ejercicio de
progrmacion.
*Actividad a realizar
*Escribir una función que devuelva la tirada de un dado de rol de n caras.
Se contemplan dados que no existirían físicamente como los de 5 caras.
*El Ejercicio resuelto lo adjunte.*
*Repuesta del profesor :*
El ejercicio está bien, no debería colocarse el srand dentro de la función o
no tendrá aleatoriedad
Donde colocar el srand.
Te contesto en linea con varios comentarios ya que estamos. Son cosas
que se van aprendiendo y que esta bueno saber desde un principio, pero
nada loco. Igual se que es un archivo de ejercicio y muchos de los
comentarios seguramente ya los sabes, pero por las dudas. Otra cosa que
esta bueno es compilar con "-Wall" que te habilita todos los warnings.
Post by vascocho
4.2a.cpp
#include <conio.h>
#include <iomanip>
#include <iostream>
#include <ctime>
#include <cstdlib>
Lo recomendado es poner solo los includes necesarios.
Post by vascocho
using namespace std;
int dado(int x);
int w;
"int w;" esta al pedo (además que es global innecesariamente).
Post by vascocho
int main() {
cout <<"\nEl resultado es: " << dado(w);
En vez de "\n" poné "endl" y ponelo al final para que ponga el enter
después de la salida y no te quede el prompt pegado. Quedaría así:

cout << "El resultado es: " << dado(w) << endl;
Post by vascocho
}
int dado(int x)//
{
srand(time(NULL)); //se obtiene una distancia al azar
int w=rand()%6+1;
return (w);
}
Bueno, acá la parte que preguntaste. Como este programa da solo un
resultado cada vez que se ejecuta da lo mismo donde este puesto el
"srand". Igual tiene un problema que es que si ejecutas varias veces el
programa en el mismo segundo, time() te va a devolver lo mismo y la
semilla para srand va a ser la misma y por lo tanto el resultado
también. En vez de usar time() podes usar getpid() por ejemplo para la
semilla a srand y funcionaría mejor.

Saludos
Andres Morales
2011-06-06 14:32:41 UTC
Permalink
Post by vascocho
Post by vascocho
Hola gracias por su ayuda aca va mi primer duda en un ejercicio de
progrmacion.
*Actividad a realizar
*Escribir una función que devuelva la tirada de un dado de rol de n
caras.
Post by vascocho
Se contemplan dados que no existirían físicamente como los de 5 caras.
*El Ejercicio resuelto lo adjunte.*
*Repuesta del profesor :*
El ejercicio está bien, no debería colocarse el srand dentro de la
función o
Post by vascocho
no tendrá aleatoriedad
Donde colocar el srand.
Te contesto en linea con varios comentarios ya que estamos. Son cosas
que se van aprendiendo y que esta bueno saber desde un principio, pero
nada loco. Igual se que es un archivo de ejercicio y muchos de los
comentarios seguramente ya los sabes, pero por las dudas. Otra cosa que
esta bueno es compilar con "-Wall" que te habilita todos los warnings.
Post by vascocho
4.2a.cpp
#include <conio.h>
#include <iomanip>
#include <iostream>
#include <ctime>
#include <cstdlib>
Lo recomendado es poner solo los includes necesarios.
Post by vascocho
using namespace std;
int dado(int x);
int w;
"int w;" esta al pedo (además que es global innecesariamente).
Post by vascocho
int main() {
cout <<"\nEl resultado es: " << dado(w);
En vez de "\n" poné "endl" y ponelo al final para que ponga el enter
cout << "El resultado es: " << dado(w) << endl;
Post by vascocho
}
int dado(int x)//
{
srand(time(NULL)); //se obtiene una distancia al azar
int w=rand()%6+1;
return (w);
}
Bueno, acá la parte que preguntaste. Como este programa da solo un
resultado cada vez que se ejecuta da lo mismo donde este puesto el
"srand". Igual tiene un problema que es que si ejecutas varias veces el
programa en el mismo segundo, time() te va a devolver lo mismo y la
semilla para srand va a ser la misma y por lo tanto el resultado
también. En vez de usar time() podes usar getpid() por ejemplo para la
semilla a srand y funcionaría mejor.
Saludos
Mmm... getpid ?

¿No te daría el mismo número de proceso si fuese el mismo programa? La
semilla sería siempre la misma, no sería aleatorio.
Sigo prefiriendo time.
v***@lugmen.org.ar
2011-06-06 14:42:24 UTC
Permalink
Post by Andres Morales
[...]
Post by v***@lugmen.org.ar
Bueno, acá la parte que preguntaste. Como este programa da solo un
resultado cada vez que se ejecuta da lo mismo donde este puesto el
"srand". Igual tiene un problema que es que si ejecutas varias veces el
programa en el mismo segundo, time() te va a devolver lo mismo y la
semilla para srand va a ser la misma y por lo tanto el resultado
también. En vez de usar time() podes usar getpid() por ejemplo para la
semilla a srand y funcionaría mejor.
Saludos
Mmm... getpid ?
¿No te daría el mismo número de proceso si fuese el mismo programa? La
semilla sería siempre la misma, no sería aleatorio.
Sigo prefiriendo time.
No, el pid cambia _seguro_ en cada ejecución y time no. Hace la prueba,
ejecuta con time() y con getpid() de esta manera y fijate:

$ while true; do <nombre_del_exe> ; done
Alejandro Vargas
2011-06-06 15:08:27 UTC
Permalink
Post by v***@lugmen.org.ar
Post by Andres Morales
¿No te daría el mismo número de proceso si fuese el mismo programa? La
semilla sería siempre la misma, no sería aleatorio.
Sigo prefiriendo time.
No, el pid cambia _seguro_ en cada ejecución y time no. Hace la prueba,
$ while true; do <nombre_del_exe> ; done
Bueno, creo que queda claro que acá hay un problema con respecto a la
semilla de los números aleatorios. Usar el process id es todavía peor
que usar los segundos en lo referente a la "predictibilidad".

De nuevo, en un caso así puede dar lo mismo pero cuando se trata de
números aleatorios, sería deseable que sean lo más impredecibles
posible. Normalmente esto se hace con algo relacionado con el tiempo,
como estaba en el programa. Lo que pasa es que tiene que ser algo más
cambiante que un conteo de segundos. En particular se suele usar los
microsegundos.
v***@lugmen.org.ar
2011-06-06 15:30:01 UTC
Permalink
Post by Alejandro Vargas
Post by v***@lugmen.org.ar
Post by Andres Morales
¿No te daría el mismo número de proceso si fuese el mismo programa? La
semilla sería siempre la misma, no sería aleatorio.
Sigo prefiriendo time.
No, el pid cambia _seguro_ en cada ejecución y time no. Hace la prueba,
$ while true; do <nombre_del_exe> ; done
Bueno, creo que queda claro que acá hay un problema con respecto a la
semilla de los números aleatorios. Usar el process id es todavía peor
que usar los segundos en lo referente a la "predictibilidad".
Peor? Eso que acabas de decir no tiene sentido. Predictibilidad de que?
De la semilla?
Post by Alejandro Vargas
De nuevo, en un caso así puede dar lo mismo pero cuando se trata de
números aleatorios, sería deseable que sean lo más impredecibles
posible. Normalmente esto se hace con algo relacionado con el tiempo,
como estaba en el programa. Lo que pasa es que tiene que ser algo más
cambiante que un conteo de segundos. En particular se suele usar los
microsegundos.
Ahora estas hablando de la que los numero aleatorios sean impredecibles.
De la forma en que esta hecho el programa, dadas varias ejecuciones
dentro del mismo segundo, usando time() los números son totalmente
predecibles, en cambio usando getpid() no lo son.
Alejandro Vargas
2011-06-06 15:34:08 UTC
Permalink
Post by v***@lugmen.org.ar
Post by Alejandro Vargas
Bueno, creo que queda claro que acá hay un problema con respecto a la
semilla de los números aleatorios. Usar el process id es todavía peor
que usar los segundos en lo referente a la "predictibilidad".
Peor? Eso que acabas de decir no tiene sentido. Predictibilidad de que?
De la semilla?
Claro. Si yo se que la semilla se toma de la cantidad de segundos, no
hay tantas alternativas si quiero probar.

No me refiero a adivinar un dado o algo así. Me refiero por ejemplo a
adivinar la semilla usada para algún tipo de cifrado. Por eso puse el
ejemplo de los de Sony.
Post by v***@lugmen.org.ar
Ahora estas hablando de la que los numero aleatorios sean impredecibles.
De la forma en que esta hecho el programa, dadas varias ejecuciones
dentro del mismo segundo, usando time() los números son totalmente
predecibles, en cambio usando getpid() no lo son.
No sólo eso. Si yo se en qué dia lo ejecutaste, tengo que hacer sólo
86400 intentos para adivinar tu número. Según el caso eso puede ser
catastrófico.
--
Qapla'
Alejandro Vargas
Loading...