portafolium set my name for the example yes I from colombia

Iniciado por hxcbps, 22 Mayo 2013, 15:01 PM

0 Miembros y 1 Visitante están viendo este tema.

hxcbps

yes I from colombia  set my name for the example portafolium

leosansan

Cita de: hxcbps en 22 Mayo 2013, 15:01 PM

la matriz debe contener 100 numeros positivos entre 1 y 100 en donde no exista un numero repetido, y los numeros sean aleatorios se imagina que una pelota se deja caer en el fondo de una piscina y que cae en alguno de los cuadros de ese piso de la piscina, la pelota va rodando por cada uno de esos cuadros que previamente tienen valores aleatorios, pero la pelota va rodando de cuadro en cuadro evaluando si pasa de menor cuadro a mayor cuadro , el usuario va controlando el moviemiento de la pelota con enter, es decir la pelota evalua los cuadros alrededor de donde esta situada, y si al cuadro que se desplaza es mayor que que el anterior que estaba lo rellenara con un cero

¡Hola, otra vez!. Y te digo lo mismo que "allí":


* Hablando con propiedad, la matriz contiene los 100 primeros números naturales, ya que al no estar repetidos no hay más posibilidades !!!.

* ¿Los números están colocados en orden natural o de forma aleatoria?.

* ¿Dónde se supone que "cae" la pelotita?, es decir, desde que casilla empieza el "juego".

* ¿Hacia dónde debe dirigirse la pelotita,?. Se mueve sí, pero que el camino a seguir dependerá del punto final no definido en el enunciado.

* ¿Qué opciones de movimiento se le presuponen a la pelotita, todo pa´lante, derecha izquierda ......?

**** Vamos que veo un poco indefinido el enunciado y no es por no ayudar, pero con algo tan indefinido......Hay que ver la importancia de definir de manera precisa e inequívoca el enunciado de un problema !!!
?
* Yo de tí empezaría por crear una matriz de de 10x10,100, algo como

int numeros[10][10]

y luego la rellenas con los100 números pero claro, ¿cómo, seguidos, alternados, pares e impares, aleatoriamente ......?.......

* Resumiendo, aclárate mejor con el enunciado y luego cuelga el código que lleves hecho y seguro que habrá quien te pueda ayudar ya que no se hacen tareas desde cero.

Saluditos! ...... ...

hxcbps

#2
portafolium 123n

5668
124560

leosansan

#3
:-)

Vamos a ver si me aclaro con lo que has hecho.

* Declaras una función como bool y le pones dos retornos "seguidos". ¿No te das cuenta que al encontrar el primer return la función "devuelve" ese valor y retorna, como su nombre indica, a la función main y por lo tanto nunca pillará el segundo return?. Conclusión, te sobra un return.

* Pero ¿la función llenar realmente tiene que devolver algo?. Lo único que hace es rellenar la matriz y punto y pelota, no devuelve nada, por lo tanto dicha función deberías declararla como void en lugar de bool.

* Ahora viene lo mejor. Llenas la matriz con números aleatorios y para evitar que se repitan haces una cosa muy curiosa. Aplicas lo siguiente:

Código (cpp) [Seleccionar]
m[i][j]=
rand() % 100 + 1;
v[i][j]=m[i][j];
   
if(m[i][j]!=v[i][j])
   m[i][j]=rand() % 100 + 1;


* Veamos, en una línea "igualas" v a m y en la siguiente, en el if, te planteas "si"  v es distinto a m hago tal cosa. ¿Pero como van a ser distintos si inmediatamente antes los has igualados?. Para que compruebes que nunca se entra en la condición del if te propongo que sustituyas el if que tienes por este otro:

Código (cpp) [Seleccionar]
if(m[i][j]!=v[i][j]){
   cout<<" entro";
   m[i][j]=rand() % 100 + 1;
   }


ejecuta el programa y verás que nunca se imprime "entro", ¡porque nunca se va a cumplir la condición de que son distintos!, los habias igualado previamente.

* Consecuencia de ello es que estas rellenado la matriz "m" con números alatorios de 1 a 1000, y claro, existe la posibilidad de que se repitan, no hay ninguna restricción para que los aleatorios que se generen sean distintos, tan solo por la casualidad o azar puede hacer que los 100 números generados entre los 1000 sean distintos, pero tan sólo sería eso, una casualidad.

* Consecuencia de la consecuencia, además de generar los aleatorios has de "idear" un sistema que te permita no repetir en cada número nuevo que generas el que coincida con los generados anteriormente. Para esto hay varias soluciones, la más inmediata y lógica es ir comparando cada nuevo valor generado con los generados anteriormente. Te lo dejo para que lo intentes. A mí personalmente, en este caso, no me parece muy eficiente ya que al menos hay que hacer 540 comparaciones. Otro método más eficiente, ya que hace "0" comparaciones , aunque coma de entrada más memoria, es llenar un vector con los 1000 números,  y tomar los elementos de la matriz  de ese vector de forma aleatoria. Incluyendo en la cabecera del código las librerías "#include <vector> y #include <algorithm>  " todo esto lo haces incluyendo en tu función llenar lo siguiente:


Código (cpp) [Seleccionar]

   int i,j;
   ................
   vector<int> n;
   for ( i=0; i<1000; ++i)n.push_back(i+1);
    random_shuffle ( n.begin(), n.end() );
   for(i=0;i<10;i++)
       for(j=0;j<10;j++)
           m[i][j]=n[(10*i)+(j+1)];
       
   }


* Lo cual nos lleva otra vez a la función llenar y mostrar , ¿para que le pasas como argumentos a i y j, que son variables que no tienen asignados ningunos valores y no "pintan" nada el pasarlos como argumentos?. Sencillamente quitalos y como te puse en el código anterior los declaras como int en la función llenar y mostrar y, de paso, quitalos también de la función main porque ahí, hasta ahora, no hacen nada.

Con lo que te he expuesto ya tienes creada la matriz de 10x10 con números del 1 al 1000 elegidos de forma aleatoria y sin repetir. Ahora te toca "mover pieza" a tí, es decir, intenta implementar la búsqueda del mínimo de la matriz, es muy fácil, una simple comparación con dos for usando tres variable que puedes llamar "minimo",imin,jmin  declaradas como int, al mismo tiempo que declaras a i y j en main si no te quieres complicar la vida, y  a partir de ahí ya te empiezas a plantear realmente el problema de cómo mover la pelotita. También puedes calcular esos valores minimos en la función llenar, pero entonces sí tendrías que pasr a la función llenar esas variables como argumentos y pasarlos por referencia, puesto que sus valores se modificarían de los declarados en la función main, que para no complicarte la vida los inicializas a cero. Pero tal como te veo de "verde", mejor lo haces en la función main. ;)

* Por cierto, no tienes bien aclarado cómo se mueve si la pelotita se encuentra en una casilla donde todas las adyacentes son menores, ¿qué hace en ese caso?. Explícalo mejor, no queda claro en el enunciado que has puesto.

Saluditos!. .....


Reeditado.

rir3760

Si me permiten un comentario (aquí voy de criticon):
Cita de: leosansan en 23 Mayo 2013, 12:10 PM
* Consecuencia de la consecuencia, además de generar los aleatorios has de "idear" un sistema que te permita no repetir en cada número nuevo que generas el que coincida con los generados anteriormente. [...]

Código (cpp) [Seleccionar]
int i, j;

// ...

vector<int> n;
random_shuffle ( n.begin(), n.end() );
for (i = 0; i < 1000; ++i)
   n.push_back(i+1);
for(i = 0; i < 10; i++)
   for (j = 0; j < 10; j++)
      m[i][j] = n[(10 * i) + (j + 1)];
}

Primero se deben agregar con push_back y solo entonces revolver con random_shuffle. Mas o menos así:
Código (cpp) [Seleccionar]
int i, j;

// ...

vector<int> n;
for (i = 0; i < 1000; ++i)
   n.push_back(i + 1);
random_shuffle(n.begin(), n.end());

for (i = 0; i < 10; i++)
   for (j = 0; j < 10; j++)
      m[i][j] = n[i * 10 + j];
}


Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

leosansan

#5
Cita de: rir3760 en 23 Mayo 2013, 16:53 PM
Código (cpp) [Seleccionar]
int i, j;

// ...

vector<int> n;
for (i = 0; i < 1000; ++i)
  n.push_back(i + 1);
random_shuffle(n.begin(), n.end());

for (i = 0; i < 10; i++)
  for (j = 0; j < 10; j++)
     m[i][j] = n[i * 10 + j];
}


Un saludo

Gracias por la observación, me disculpa un poco que estoy haciendo los códigos "a pelo", me crujió  CodeBlocks tras una dichosa actualización del WindowsUpdate.

Y para que esta aportación no se quede en unas meras disculpas, propongo el método alternativo de generar los números por comparación con los previamente introducidos, sería para sustituir por lo que hay "encima" de estas palabras:


Código (cpp) [Seleccionar]

........................
for( i = 0; i < 100; i++){
       numeros[i]=rand() % 1000+1;
       for( j = i-1; j >=0 ; j--){
           if(numeros[i] == numeros[j]){
               i--;
               break;
           }
       }
   }
   cout<<endl;   cout<<endl;
   for(i=0;i<10;i++){
       for(j=0;j<10;j++){
           p[i][j]=numeros[k++];
           cout<<m[i][j]<<"  ";
           }
       cout<<endl;
   }


Aunque seguro que se puede mejorar, la verdad no me termina de convencer el for con el if y el i-- con break, pero funciona, digo simplemente que alguien más curtido en C/C++ seguramente lo podrá mejorar. Y yo estoy deseoso que sea así, ¿coges la indirecta amigo rir?

Saluditos!. .... ..

CCross

#6
Hey, que tal me estaba aburriendo y decidi a hacer este programita  ;D genera
numeros aleatorios y los guarda en una matriz y implemento una funcion que comprueba
si el numero es repetido. Creo que le puede servir a hxcbps ahora estoy trabajando
en la version de punteros jejep.

Código (cpp) [Seleccionar]
#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

bool repite(int n, int _matriz[10][10])
{
   for(int i=0; i<10; i++)
      for(int j=0; j<10; j++)
       if(n == _matriz[i][j])return true;
         return false;
}
int main()
{
   srand(time(NULL));
   int matriz[10][10] = {0}, n;

   for(int i=0; i<10; i++)
       for(int j=0; j<10; j++){
           do
              n = 1+ rand() % 100;
           while(repite(n, matriz));
              matriz[i][j] = n;
              cout << matriz[i][j] << "  ";
       }
   cin.get();
   return 0;
}


Saludos.

hxcbps

#7
3453454
3455345





mr.blood

#8
Dejo una alternativa que me parece que es más eficaz. (No recorre toda la matriz para comprobar si existe o no el valor).

Como necesitas tener todos los números del 0-99 es mejor aleatorizar la posición que el valor (Creo). ;)


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int main()
{
srand(time(NULL));
int matriz[10][10], i, j, x, y;

memset(matriz, 0, sizeof(int)*100);

for(i=0;i<100;i++)
{
x=rand()%10;
y=rand()%10;
if(matriz[x][y]==0)
{
matriz[x][y]=i;
}
else
{
i--;
continue;
}

}

for(i=0;i<10;i++)
{
putchar('\n');
for(j=0;j<10;j++)
printf("%i\t", matriz[i][j]);
}

return 0;
}


EDITO:
El tiempo baja de 0.007s a 0.003s (a veces es 0.004 y el máximo son 0.005 pero los habitual es 0.003) casi la mitad ;). Creo que aun se puede mejorar el código.

Añado otro código que hace que casi hasta el 80 se rellene del tirón, creo que puede hacerse sin tanto if, pero no tengo más tiempo hoy. Este código comprueba si las celdas cercanas están en 0 para no tener que repetir el ciclo tantas veces. Creo que aún se puede hacer en menos ciclos del for. Ahora usará unos 129.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int main()
{
srand(time(NULL));
int matriz[10][10], i, j, x, y;

memset(matriz, 0, sizeof(int)*100);

for(i=0;i<100;i++)
{
printf("%i\n", i);
x=rand()%10;
y=rand()%10;
if(matriz[x][y]==0)
{
matriz[x][y]=i;
}
else
{
if(matriz[x][y+1]==0 && y+1<10)
{
matriz[x][y+1]=i;
continue;
}
if(matriz[x][y-1]==0 && y-1>=0)
{
matriz[x][y-1]=i;
continue;
}
if(matriz[x-1][y]==0 && x-1>=0)
{
matriz[x-1][y]=i;
continue;
}
if(matriz[x-1][y-1]==0 && x-1>=0 && y-1>=0)
{
matriz[x-1][y-1]=i;
continue;
}
if(matriz[x-1][y+1]==0 && x-1>=0 && y+1<10)
{
matriz[x-1][y+1]=i;
continue;
}
if(matriz[x+1][y]==0 && x+1<10)
{
matriz[x+1][y]=i;
continue;
}
if(matriz[x+1][y-1]==0 && x+1<10 && y-1>=0)
{
matriz[x+1][y-1]=i;
continue;
}
if(matriz[x+1][y+1]==0 && x+1<10 && y+1<10)
{
matriz[x+1][y+1]=i;
continue;
}
i--;
continue;
}

}

for(i=0;i<10;i++)
{
putchar('\n');
for(j=0;j<10;j++)
printf("%i\t", matriz[i][j]);
}

return 0;
}


Sa1uDoS

leosansan

#9
Cita de: mr.blood en 24 Mayo 2013, 08:35 AM
Dejo una alternativa que me parece que es más eficaz. (No recorre toda la matriz para comprobar si existe o no el valor).

Como necesitas tener todos los números del 0-99 es mejor aleatorizar la posición que el valor (Creo). ;)

...................................

Sa1uDoS

El problema es que los 100 números que necesita son entre 0 y 1000.

Lástima porque la idea era buena.
 
Lamentablemente no tengo compilador en este momento y no puedo comparar, pero creo que siguiendo lo que planteaste de obtener aleatorios de 0 a 100, aunque recuerda que en realidad era "entre" 0 y 10000, el siguiente código podría ser de eficiencia/velocidad semejante.:

Código (cpp) [Seleccionar]

#include <iostream>    
#include <algorithm>    
#include <vector>      
#include <ctime>        
#include <cstdlib>
using namespace std;

int main()
{
   int i,j,k=0;
   int m[10][10],numeros[100];
   srand ( unsigned ( std::time(0) ) );
   vector<int> n;
   for ( i=0; i<100; ++i)n.push_back(i+1);
   random_shuffle ( n.begin(), n.end() );
   for(i=0;i<10;i++,k++) {
       for(j=0;j<10;j++,k++){
           m[i][j]=n[k];
       cout<<m[i][j]<<"\t";
       }
       k--;
       cout<<endl;
   }  
   system("pause") ;
   return 0;
}



Aunque para realizar comparaciones de "potencia de cálculo" habría que suprimir la impresión de la matriz al completo y poner un sólo puts, o printf o cout que indique el final del proceso ya que si no el resultado de tiempos estará "muy" influenciado por la tarjeta gráfica, me refiero a la hora de comparar resultados entre distintas máquinas con procesador parecido.

Por aportar algo diferente pongo este código con un do-while  que, a diferencia del for, no tiene que restar (i--) por lo que se presupone algo mas eficiente.Es un decir porque cambia el i++ por una comparación.  Pero al hablar de eficiencia tendríamos que comparar con matrices muy superiores en dimensión para que fueran perceptibles esas diferencias. Pero bueno, como ejercicio no rstá mal lo que est´s dsliendo de este tema.


Código (cpp) [Seleccionar]
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
srand(time(NULL));
int matriz[10][10]={0}, i=0, j,x,y;
do{
x=rand()%10;
y=rand()%10;
if (matriz[x][y]==0){
            matriz[x][y]=i;
            i++;

}

}while (i<100);

for(i=0;i<10;i++)
{
putchar('\n');
for(j=0;j<10;j++)
printf("%i\t", matriz[i][j]);
}
    return 0;
}


Por otro lado sería interesante  comparar realizando el cálculo con varios hilos a ver la influencia del multiproceso/multiCPU, suponiendo que el compilador está preparado para hacer uso de los multinúcleos.

Y en el segundo código hay que empezar por el valor menor de los generados aleatoriamente, que habrá que saber cuál es, así como su posición inicial, para a partir de la misma empezar el movimiento. Eso daría como resultado sólo cuatro comparaciones en cada posición a realizar por comodidad con una función, ya que en cada movimiento hay que volver a comparar.

En definitiva, has  animado este post, aunque, repito, te salieras del guión.

Saluditos!. ... ..[/size]



P.D: Esta noche cuelgo el código con los valores tomados de 1 a 1000 "sin hacer comparaciones".