[ Foro de Pascal ]
Hola!
Pues eso...creo un array con tres valores:
program arreglo_01;
uses
crt;
var
arreglo : array[1..3] of byte;
begin
arreglo[1] := 6;
arreglo[2] := 10;
arreglo[3] := 24;
end.
Pero no sé como aplicar el random para que me dé aleatoriamente un valor de esos tres.
He probado:
arreglo[random]; // No funciona
Otra cosa es crear el indice del arreglo con una variable:
arreglo[i];
Entonces:
random(arreglo[i]); // Tampoco me va :(
Si usamos la variable del indice se debería usar un For, claro...
En esa estamos... :(
Este es el programa que he creado. Pero creo, hago un mal uso del random. Ya que me genera un número aleatorio que no se encuentra entre los escogidos por nosotros...
program arreglo_aleatorio;
uses
crt;
var
aleat : array[1..3] of byte;
i : byte;
begin
for i := 1 to 3 do
begin
writeln('Escoge un numero...');
write(i,'. ');
readln(aleat[i]);
end;
textcolor(yellow);
writeln('Has escogido...');
for i := 1 to 3 do
begin
write(aleat[i]);
writeln();
end;
textcolor(green);
writeln('Numero aleatorio: ');
writeln(random(aleat[i]));
end.
Efectivamente estás usando mal la función random. Lo correcto sería así:
i:= random(3) + 1; (* De esta forma estaría generando un valor aleatorio comprendido *)
(* entre 1 y 3, el cual lo almacenamos en la variable i *)
writeln(aleat[i]); (* Al haber generado el índice aleatoriamente, estamos generando *)
(* un valor aleatorio del arreglo aleat[i] *)
Saludos.
No es a lo que me referiría.
Se trata de que nosotros escogemos tres valores por medio de readln(aleat[i]) dentro de un ciclo for. Por ejemplo:
3, 11, 34
Y el random nos debe generar un número aleatorio dentro de esos tres (3,11,34). No del 1 al 3.
En cuanto tienes un valor del 1 al 3, ya puedes obtener los valores 3, 11, 34 del array, porque esos son sus índices.
La respuesta de Luis es correcta.
Puedes pedir los datos al usuario con "readln(dato[i])" y luego escoges uno de ellos al azar de la forma que te ha indicado Luis.
Anda! Pues teníais razón los dos. Era yo que no lo había entendido. Muchas gracias y disculpas ;)
Ahora me surge un nuevo problema basado en este código. El número aleatorio ya me lo da ¿Pero como puedo pedirle 3 sobre los 6 seleccionados? He probado con un for y un repeat y no me funciona.
El for queda así:
for i := 1 to 3 do
begin
randomize;
i := random(3) + 1;
writeln(aleat[i]);
end;
Pero claro, la varible 'i' se ve alterada por el random y el for no se puede ejecutar. Y con el repeat me da el mismo número 3 veces seguidas:
contador := 0;
repeat
randomize;
i := random(3) + 1;
writeln(aleat[i]);
contador := contador + 1;
until contador = 3;
Cada vez que se soluciona un problema, sale otro. Supongo que esto será el arte de programar ;)
Saca el randomize del repeat - until. Ponlo antes de iniciar ese ciclo.
Saludos.
Ok. Como has dicho tú, funciona ¿Pero no debería estar dentro para cambiar la semilla de la aleatoriedad? Por que al estar fuera del ciclo, esa semilla no se regenera o reinicia ¿No...?
Saludos!
El profesor Nacho te podrá explicar más al respecto, pero lo que yo sí sé es que randomize se debe ejecutar una sola vez en el programa. Yo hice un código que genera cada uno de los elementos del arreglo aleat, sin que se repita el elemento que ya se generó, es decir, impide que aparezcan dos veces un mismo elemento. Para ello hice uso de "Conjuntos" en Pascal. Aquí te lo dejo:
program NumerosAleatorios;
const
aleat: array[1..3] of integer = (6,10,24);
type
conjNum = set of byte; { Creamos un tipo Conjunto }
var
i, contador: integer;
num: conjNum; { Definimos una variable de un tipo Conjunto }
BEGIN
randomize;
contador:= 0;
num:=[]; { Inicializamos la varible con el conjunto vacío }
repeat
i:= random(3) + 1;
if not(i in num) then { Si el índice del elemento no está en el conjunto }
begin
num:= num + [i]; { Incluimos el índice del elemento en el conjunto }
writeln(aleat[i]);
contador:= contador + 1;
end;
until contador=3;
readln;
END.
¡Anda! Pues muchas gracias. Precisamente ahora estaba liado con eso. Es decir, que de los tres números que nos generara el código, no se repitiera ninguno de ellos. Había pensado usar un while. Mas que nada por que todavía no he llegado a la lección de conjuntos. Y he visto cosas en tu código que aún no conozco. De todas formas, muy agradecido. Me lo guardo para cuando llegue ahí.
Saludos!
Efectivamente: randomize inicia la generación de números aleatorios, a partir de una semilla tomada del reloj interno del equipo. Si repites el randomize, obtendrás varias secuencias iguales, en vez de una única secuencia cambiante.
Ok.
Sobre este mismo ejemplo (Luis a usado conjuntos), ¿Cómo debería ser para no repetir los tres números? ¿Usando una variable auxiliar?
Por que no puedo comparar la variable 'i' consigo misma. Se trata que dentro del repeat use un while o un if para comparar dicho indice de 'i'. Si lo hago, el programa se para y no da ningún resultado.
contador := 0;
randomize;
repeat
i := random(6) + 1;
while i = i do
i := random(6) + 1;
writeln(i, ' ',aleat[i]);
contador := contador + 1;
until contador = 3 ;
Le pido que si el indice es igual al salido anteriormente, me genere otro indice. De esa forma, no se repetiría el número. Pero dudo que esto sea correcto. De todas formas, lo he probado con una variable auxiliar y tampoco me va.
La solución que encontré fue crear un nuevo vector de la misma dimensión que el vector aleat, este vector va a almacenar datos booleanos, si ya se generó el número en la posición i, entonces el vector adquiere el valor "true" en esa posición. A mí me parece que solucionarlo con conjuntos queda mucho más claro, no necesitas aprenderte toda la teoría de conjuntos, en poco tiempo la dominarás. Bueno, aquí te dejo el código:
program NumerosAleatorios;
const
aleat: array[1..3] of integer = (6,10,24);
Vector_encontrados: array[1..3] of boolean =(false,false,false);
var
i, contador: integer;
BEGIN
randomize;
contador:= 0;
repeat
i:= random(3) + 1;
if Vector_encontrados[i]=false then
begin
Vector_encontrados[i]:= true;
writeln(aleat[i]);
contador:= contador + 1;
end;
until contador=3;
readln;
END.
hola amigos del foro, me atrajo este ejercicio y las soluciones que da luis y el profesor.
queria preguntarle al compañero luis, si pudiera explicarme una cuestion respecto a su primer codigo completo con conjuntos:
num:=[]; { Inicializamos la varible con el conjunto vacío }
repeat
i:= random(3) + 1;
if not(i in num) then
...
cuando entras al repeat y haces el if, en ese instante conque valor de num , se esta comparando el i aleatorio obtenido? osea que valor tiene num,¿vacio?, se puede comparar un valor indice con el valor vacio?
Num es un "conjunto" (debes recordar toda la teoría de conjuntos que viste en la educación primaria). Num es un conjunto vacío que puede albergar números desde el 0 hasta 255 (tipo byte).
Cuando escribimos if not(i in num) then , simplemente estamos preguntando si el elemento guardado en la variable i "pertenece" (teoría de conjuntos, recuérdala!) al conjunto Num. O sea, sería más o menos así:
i ? Num ?
Debes ver a Num NO como una variable, sino más bien como lo que tú conoces de lo que es un conjunto. Si el elemento guardado en i no está en ese conjunto, entonces hay una instrucción que agrega ese elemento al conjunto Num, el cual ya dejará de ser vacío para contener a su primer elemento.
Eso es todo, de allí que sea más sencillo hacer el programa con conjuntos, claro está, una vez que te familiarices con esta forma nueva de expresarte.
Saludos.
hola muchisimas gracias luis, eres un compañero bastante colaborativo para quienes estamos iniciandonos, gracias por tu paciencia , entiendo lo que me dices ahora, pero porfa dame un si o un no a quiza lo mismo aunque entendiendolo ahora mejor, en ese caso la primera vez que:
escribimos if not(i in num) then , simplemente estamos preguntando si el elemento guardado en la variable i "pertenece" al conjunto num, estaria preguntando si ese i aleatorio generado( 1, 2 o 3) esta en el conjunto num=[], lo cual seria falso inicialmente, estoy en lo correcto luis? disculpame pero asi estaria tranquilo de haber entendido esto de conjuntos gracias a ti.un saludo compañero
Gracias de nuevo, Luis. Intentaré "copiar" tu sistema de conjuntos y aplicarlo sin ellos. Mas que nada para no avanzar mas que el curso de Nacho. Cuando me funcione, lo posteo. Aunque viendo que tu has aplicado los conjuntos, deduzco, que como lo quiero hacer yo, será mas complicado :(
Saludos!
Marc, si quieres practicar un poco más con conjuntos, aquí tienes las ideas básicas:
http://nachocabanes.com/pascal/cupas5/cupas04d.php
(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)