[Curso] Introducción a la programación en C (IX)

Moderadores: Kravenbcn, largeroliker, fidelcastro, cerealkiller, pspCaracas, m0skit0, LnD, ka69, zacky06

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: [Curso] Introducción a la programación en C (IX)

Mensaje por m0skit0 »

Dark Pallacus escribió:Por cierto, hay alguna orden para ordenar diferentes variables de mayor a menor?

¿"Orden"? :lol: No te he entendido, explíquese señor Pallacus.
Imagen

Avatar de Usuario
Dark Pallacus
ViP Hordes
ViP Hordes
Mensajes: 1509
Registrado: 03 Sep 2009, 00:35
PSN ID: Pallacus
Ubicación: Barcelona
Contactar:

Re: [Curso] Introducción a la programación en C (IX)

Mensaje por Dark Pallacus »

Función? :oops: :?: :? :)
Comando? :oops:
Instrucción? :oops: :?: :?
PS3 - PSP 2000

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: [Curso] Introducción a la programación en C (IX)

Mensaje por m0skit0 »

Vale, pero sigue sin entender lo que quieres. Dame más detalles.
Imagen

Avatar de Usuario
Dark Pallacus
ViP Hordes
ViP Hordes
Mensajes: 1509
Registrado: 03 Sep 2009, 00:35
PSN ID: Pallacus
Ubicación: Barcelona
Contactar:

Re: [Curso] Introducción a la programación en C (IX)

Mensaje por Dark Pallacus »

Mejor explicar toda la verdad:
Después de hacer el programa de la lotería, he querido hacer uno para la Primitiva. (Sacar 6 bolas de 49. Incluso sacar luego otra bola complementaria y hacer otro sorteo para el reintegro.)

Al principio saco una bola de 49. Luego saco otra de las 48 que quedan dentro. Compruebo que no se repita el número y de ser así le sumo 1 a la última bola sacada. Lo que quedaría así.
Spoiler:

Código: Seleccionar todo

  printf("\n Sorteos tongo!\n La combinación ganadora de hoy es:\n ");
 
  //Sacamos las bolas del sorteo.
  //Primera bola. (Hay 49 bolas en el bombo)
  bola_1 = (rand() % 49) + 1;
  printf("%d, ", bola_1);
 
  //Segunda bola. (Quedan 48 bolas en el bombo)
  bola_2 = (rand() % 48) + 1;
  //Si sale el mismo resultado, saltamos al siguiente.
  if (bola_2 == bola_1)
  {
    bola_2 ++;
  }
  printf("%d, ", bola_2);
 
  //Tercera bola. (Quedan 47 bolas en el bombo)
  bola_3 = (rand() % 47) + 1;
  //Si el número coincide con cualquiera de los anteriores, saltamos al siguiente.
  while (!((bola_3 != bola_2) && (bola_3 != bola_1)))
  {
    bola_3 ++;
  }
  printf("%d, ", bola_3);
Usando este método, no saldría nunca un 48 ó 49 como bola_4 o bola_5 a menos que la mayoría de bolas sacadas fueran de las mas altas (47, 48...)

Por tanto he cambiado a otro método: Si la bola extraída es mayor que la primera le sumo 1 a la bola extraída y así desplazo el resultado para cubrir todas las bolas posibles hasta el 49.
Spoiler:

Código: Seleccionar todo

printf("\n Sorteos tongo!\n La combinación ganadora de hoy es:\n ");
 
  //Sacamos las bolas del sorteo.
  //Primera bola. (Hay 49 bolas en el bombo)
  bola_1 = (rand() % 49) + 1;
  printf("%d, ", bola_1);
 
  //Segunda bola. (Quedan 48 bolas en el bombo)
  bola_2 = (rand() % 48) + 1;
  //En el bombo falta una bola, si sale el mismo resultado o superior, corremos el resultado hacia arriba.
  if (bola_2 >= bola_1)
  {
    bola_2 ++;
  }
  printf("%d, ", bola_2);
 
  //Tercera bola. (Quedan 47 bolas en el bombo)
  bola_3 = (rand() % 47) + 1;
  //Corregimos el resulado.
  if (bola_3 >= bola_1)
  {
    bola_3 ++;
  }
  if (bola_3 >= bola_2)
  {
    bola_3 ++;
  }
  printf("%d, ", bola_3);
 

Yo era feliz, hasta que probandolo me ha aparecido: bola1: 44, bola2: 9, bola3: 44.....
Y me he dado cuenta de que bola_3 habia salido = 43
al ser menor de 44 no ha hecho nada.
al ser mayor que 9 le ha sumado uno.

Por esto he pensado que antes de comparar las bolas debo ordenarlas para empezar por el resultado menor.

Aunque ahora veo mas sencillo sacar siempre 1 bola de 49 y si ya ha salido repetir la extracción. Aunque esto suponga un incremento de uso del procesador :P

Aplicando a todas las bolas:
Spoiler:

Código: Seleccionar todo

//Tercera bola.
  bola_3 = (rand() % 49) + 1;
  while !((bola_2 != bola_1) && (bola_3!=bola_2))
  {
    bola_3 = (rand() % 49) + 1;
  }
  printf("%d, ", bola_3);
 


EDITO:

Anda que menuda comida de tarro os he pegado. :P

Lo cual quedaría así: (He hecho algunas pruebas y creo que no debería fallar.)
Spoiler:

Código: Seleccionar todo

//La primitiva consiste en un sorteo del que se extraen 6 números del 1 al 49 mas otro número complementario. Finalmente se extrae otro número, del 0 al 9, de otro bombo.

//Incluimos las  librerias.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(int argc, char* argv[])
{
  //Establecemos las variables.
  int bola_1, bola_2, bola_3, bola_4, bola_5, bola_6, complementario, reintegro;
 
  //Iniciamos el generador de números aleatorios,
  srand(time(NULL));
 
  printf("\n Sorteos tongo!\n La combinación ganadora de hoy es:\n ");
 
  //Sacamos las bolas del sorteo.
  //Primera bola. (Hay 49 bolas en el bombo)
  bola_1 = (rand() % 49) + 1;
  printf("%d, ", bola_1);
 
  //Segunda bola.
  bola_2 = (rand() % 49) + 1;
  //Si esta bola ya ha salido repetimos la extracción.
  while (!(bola_2 != bola_1))
  {
    bola_2 = (rand() % 49) + 1;
  }
  printf("%d, ", bola_2);
 
  //Tercera bola.
  bola_3 = (rand() % 49) + 1;
  while (!((bola_3 != bola_1) && (bola_3!=bola_2)))
  {
    bola_3 = (rand() % 49) + 1;
  }
  printf("%d, ", bola_3);
 
  //Cuarta bola.
  bola_4 = (rand() % 49) + 1;
  while (!((bola_4 != bola_1) && (bola_4 != bola_2) && (bola_4 != bola_3)))
  {
    bola_4 = (rand() % 49) + 1;
  }
  printf("%d, ", bola_4);
   
  //Quinta bola.
  bola_5 = (rand() % 49) + 1;
  while (!((bola_5 != bola_1) && (bola_5 != bola_2) && (bola_5 != bola_3) && (bola_5 != bola_4)))
  {
    bola_5 = (rand() % 49) + 1;
  }
  printf("%d, ", bola_5);
   
  //Sexta bola.
  bola_6 = (rand() % 49) + 1;
  while (!((bola_6 != bola_1) && (bola_6 != bola_2) && (bola_6 != bola_3) && (bola_6 != bola_4) && (bola_6 != bola_5)))
  {
    bola_6 = (rand() % 49) + 1;
  }
  printf("%d, ", bola_6);
   
  //Bola complementaria.
  complementario = (rand() % 49) + 1;
  while (!((complementario != bola_1) && (complementario != bola_2) && (complementario != bola_3) && (complementario != bola_4) && (complementario != bola_5) && (complementario != bola_6)))
  {
     complementario = (rand() % 49) + 1;
  }
  printf("\n\n Complementario : %d", complementario);
 
  //Y finalmente el reintegro. 1 bola del 0 al 9.
  reintegro = rand() % 10;
  printf("\n Reintegro : %d\n\n", reintegro);
 
  return 0;
}

 
Ejecutado:

Código: Seleccionar todo

albert@albert-K50IE:~/Documents/Programació/C/Lección 09/Ejercicios$ ./primitivac

 Sorteos tongo!
 La combinación ganadora de hoy es:
 11, 31, 9, 1, 7, 42,

 Complementario : 3
 Reintegro : 2

albert@albert-K50IE:~/Documents/Programació/C/Lección 09/Ejercicios$ ./primitivac

 Sorteos tongo!
 La combinación ganadora de hoy es:
 18, 48, 15, 23, 40, 49,

 Complementario : 33
 Reintegro : 4

albert@albert-K50IE:~/Documents/Programació/C/Lección 09/Ejercicios$ ./primitivac

 Sorteos tongo!
 La combinación ganadora de hoy es:
 15, 48, 17, 4, 22, 23,

 Complementario : 3
 Reintegro : 8

albert@albert-K50IE:~/Documents/Programació/C/Lección 09/Ejercicios$
Ha salido un 49 en sexto lugar. XD XD XD
Y parece que no se repiten bolas.
PS3 - PSP 2000

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: [Curso] Introducción a la programación en C (IX)

Mensaje por m0skit0 »

Buena comida de tarro :lol:

Lo que pasa, querido Pallacus, es que existe lo que se llaman vectores (o arrays para los amantes Shakespeare). En vez de tener X variables, se puede tener un vector, que es como varias variables a la vez.

Por ejemplo, si tú quieres tener 6 bolas, puedes declarar un vector de 6 enteros tal que:

Código: Seleccionar todo

int bolas[6];

Esto significa que bolas es un vector de 6 posiciones de tipo entero. Para acceder a los elementos del vector, hacemos:

Código: Seleccionar todo

bolas[0] -> primer elemento
bolas[1] -> segundo elemento
...
bolas[5] -> sexto y último elemento

Por tanto para recorrer por ejemplo todo el vector e imprimir sus valores, bastaría con hacer:

Código: Seleccionar todo

for (i=0; i<6; i++)
{
   printf("%d ", bolas[i]);
}

A ver si se te ocurre cómo usar esto en tu código ;)
Imagen

Avatar de Usuario
Dark Pallacus
ViP Hordes
ViP Hordes
Mensajes: 1509
Registrado: 03 Sep 2009, 00:35
PSN ID: Pallacus
Ubicación: Barcelona
Contactar:

Re: [Curso] Introducción a la programación en C (IX)

Mensaje por Dark Pallacus »

:baba:
Ya vi que alguien usaba vectores por ahí. XD
Luego le doy a la sesera, que todavía estoy despertando :P

EDITO:

Tras mucho romperme la cabeza, y quedarme bloqueado varias veces, he escrito esto:
Spoiler:

Código: Seleccionar todo

//La primitiva consiste en un sorteo del que se extraen 6 números del 1 al 49 mas otro número complementario. Finalmente se extrae otro número, del 0 al 9, de otro bombo.

//Incluimos las  librerias.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(int argc, char* argv[])
{
  //Establecemos las variables. Inicializamos todas las bolas con valor 0.
  int bola[7]={0}, bola_actual, extraccion, impresion, reintegro;
 
  //Iniciamos el generador de números aleatorios,
  srand(time(NULL));
 
  //Imprimimos la cabecera.
  printf("\n Sorteos tongo!\n La combinación ganadora de hoy es:\n ");
 
  //Sacamos las 7 bolas. Si la bola extraída coincide con alguna anterior se vuelve a extraer.
  for (extraccion = 0; extraccion < 7; extraccion++)
  {
    bola_actual = (rand() % 49) + 1;
    while (!((bola_actual != bola[0]) && (bola_actual != bola[1]) && (bola_actual != bola[2]) && (bola_actual != bola[3]) && (bola_actual != bola[4]) && (bola_actual != bola[5]) && (bola_actual != bola[6])))
    {
      //printf("%d repetido\n", extraccion);//Con esta línea es mas facil ver cuando se ejecuta el while.
      bola_actual = (rand() % 49) + 1;
    }
    bola[extraccion] = bola_actual;
  }
  //Sacamos también el reintegro.
  reintegro = rand() % 10;
 
  //Imprimimos los resultados de las 6 bolas...
  for (impresion = 0 ; impresion < 6 ; impresion++)
  {
    printf("%d, ", bola[impresion]);
  }
 
  // el complementario...
  printf("\n Complementario: %d", bola[6]);
 
  // y el reintegro.
  printf("\n Reintegro : %d\n\n", reintegro);
 
  return 0;
}
Me gustaría simplificar el while, es demasiado largo. Y por eso me ha costado tanto (sobremanera) descubrir donde me había dejado un paréntesis que hacia que no se ejecutara. :tongue:
Existen comodines para comparar "bola_actual" con todos elementos de "bola[*]" ?
PS3 - PSP 2000

Avatar de Usuario
~Rdavid~
Experto
Experto
Mensajes: 965
Registrado: 12 Nov 2009, 17:29
Ubicación: Costa Rica

Re: [Curso] Introducción a la programación en C (IX)

Mensaje por ~Rdavid~ »

Dark Pallacus escribió:Me gustaría simplificar el while, es demasiado largo. Y por eso me ha costado tanto (sobremanera) descubrir donde me había dejado un paréntesis que hacia que no se ejecutara


Creo que hacer while(!((bola != bola_actual[0])......
es lo mismo que hacer while((bola==bola_actual[0]).....


Dark Pallacus escribió:Existen comodines para comparar "bola_actual" con todos elementos de "bola[*]" ?


Puedes hacerlo con un bucle for, algo así

Código: Seleccionar todo

for(i=0;i<n;i++)
{
     if(bola_actual == bola[i])//Si son iguales...
     {
           .......
     }
}
Imagen

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: [Curso] Introducción a la programación en C (IX)

Mensaje por m0skit0 »

Buen intento, aunque fallido ;)

Código: Seleccionar todo

int bola[7]={0}, bola_actual, extraccion, impresion, reintegro;

Primero, intenta no mezclar declaraciones de vectores con no vectores, e inicializaciones con otras declaraciones, queda demasiado confuso.

int bola[7]? Pero no eran 6 bolas? No me líes :lol:

int bola[7] = {0} no inicializa todos los elementos, sino sólo el primero a 0. Tienes dos opciones para lo que quieres hacer:

Código: Seleccionar todo

// Esto:
int bola[7] = {0,0,0,0,0,0,0};
// O esto:
int i;
for (i = 0; i < 7; i++)
{
    bola[i] = 0;
}


Código: Seleccionar todo

while (!((bola_actual != bola[0]) && (bola_actual != bola[1]) && (bola_actual != bola[2]) && (bola_actual != bola[3]) && (bola_actual != bola[4]) && (bola_actual != bola[5]) && (bola_actual != bola[6])))

El utilizar un vector es precisamente para evitar este tipo de sentencias. Como dice ~Rdavid~ está mejor, pero no exactamente como lo ha puesto, que se queda cojo por tener que usar break. Mejor así (no lo he probado, no me riñáis si no funciona :lol: ):

Código: Seleccionar todo

int i = 0;
while (i < 7)
{
    if (bola_actual == bola[i])
    {
        i = 0;
        bola_actual = (rand() % 49) + 1;
    }
    else
    {
        i++;
    }
}

Cuando no se deban recorrer todos los elementos, siempre se usa while y no for. For es para cuando sabemos de antemano cuántas repeticiones tenemos. Cuando veas funciones verás que se simplifica aún más (bueno, en realidad es lo mismo, pero queda más limpio :D ).

Ah, y un ultimo consejo: siempre es conveniente nombrar los vectores en plural, es decir bolas y no bola. Así sabes que son varios, y por tanto un vector.
Imagen

Avatar de Usuario
Dark Pallacus
ViP Hordes
ViP Hordes
Mensajes: 1509
Registrado: 03 Sep 2009, 00:35
PSN ID: Pallacus
Ubicación: Barcelona
Contactar:

Re: [Curso] Introducción a la programación en C (IX)

Mensaje por Dark Pallacus »

Ok, una consideración: Debo comprobar todas las bolas a la vez, lo veréis. mas claro con este caso que me encontré. Si comprobamos las bolas una a una:

bola1 = 44
bola2 = 43
si bola3 = 43: es diferente a 44, salta la comprobación y se compara con bola2. bola3 = bola2, por tanto adquiere un nuevo valor que puede ser 44 y quedaría repetido.

Por eso uso la expresión "si no es diferente a todas -> repito la extracción".
int bola[7]? Pero no eran 6 bolas? No me líes :lol:
Del bombo de 49 bolas se sacan 7. 6 + el complementario ;)

Modificado: Vectores a parte y en plural.
Spoiler:

Código: Seleccionar todo

//La primitiva consiste en un sorteo del que se extraen 6 números del 1 al 49 mas otro número complementario. Finalmente se extrae otro número, del 0 al 9, de otro bombo.

//Incluimos las  librerias.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(int argc, char* argv[])
{
  //Establecemos las variables. Inicializamos todas las bolass con valor 0.
  int extraccion, bola_actual, reintegro, impresion;
  int bolas[7]={0,0,0,0,0,0,0};
 
  //Iniciamos el generador de números aleatorios,
  srand(time(NULL));
 
  //Imprimimos la cabecera.
  printf("\n Sorteos tongo!\n La combinación ganadora de hoy es:\n ");
 
  //Sacamos las 7 bolass. Si la bolas extraída coincide con alguna anterior se vuelve a extraer.
  for (extraccion = 0; extraccion < 7; extraccion++)
  {
    bola_actual = (rand() % 49) + 1;
    while (!((bola_actual != bolas[0]) && (bola_actual != bolas[1]) && (bola_actual != bolas[2]) && (bola_actual != bolas[3]) && (bola_actual != bolas[4]) && (bola_actual != bolas[5]) && (bola_actual != bolas[6])))
    {
      //printf("%d repetido\n ", extraccion);//Con esta línea es mas facil ver cuando se ejecuta el while.
      bola_actual = (rand() % 49) + 1;
    }
    bolas[extraccion] = bola_actual;
  }
  //Sacamos también el reintegro.
  reintegro = rand() % 10;
 
  //Imprimimos los resultados de las 6 bolass...
  for (impresion = 0 ; impresion < 6 ; impresion++)
  {
    printf("%d, ", bolas[impresion]);
  }
 
  // el complementario...
  printf("\n Complementario: %d", bolas[6]);
 
  // y el reintegro.
  printf("\n Reintegro : %d\n\n", reintegro);
 
  return 0;
}
En cuanto a la inicialización solo puedo decir:
Spoiler:

Código: Seleccionar todo

//Incluimos las  librerias.
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
  int no[7];
  int si[7]={0};
  int contador;
 
  printf("\n no : ");
  for(contador = 0;contador <= 7; contador ++)
  {
    printf("%d, ", no[contador]);
  }
  printf("\n si : ");
  for(contador = 0;contador <= 7; contador ++)
  {
    printf("%d, ", si[contador]);
  }
  printf("\n\n");
 
  return 0;
}

 

Código: Seleccionar todo

albert@albert-K50IE:~/Documents/Programació/C/Lección 09/Ejercicios$ ./prueba
 no : 0, 0, 4195424, 0, -97421136, 32767, 0, 7,
 si : 0, 0, 0, 0, 0, 0, 0, 0,


~Rdavid~ escribió:Creo que hacer while(!((bola != bola_actual[0])......
es lo mismo que hacer while((bola==bola_actual[0]).....
Tengo que compararlas todas a la vez y solo puedo usar un && (y lógico) o un OR (o lógico).
Última edición por Dark Pallacus el 20 Ene 2011, 10:55, editado 1 vez en total.
PS3 - PSP 2000

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: [Curso] Introducción a la programación en C (IX)

Mensaje por m0skit0 »

Eso consideración ya la tuve en cuenta, querido Pallacus. Fíjate en mi bucle while:

Código: Seleccionar todo

    if (bola_actual == bola[i])
    {
        i = 0;
        bola_actual = (rand() % 49) + 1;
    }

Si la bola es igual, generamos nueva bola y volvemos a comparar desde el principio (i=0).

Y hablando de expresiones lógicas, conviene recordar esta regla (Regla de De Morgan):

Código: Seleccionar todo

(a && b) = !(a || b) 
(a || b) = !(a && b)

Saludos
Imagen

Responder