Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Yoldy en 9 Mayo 2017, 03:06 am



Título: Matriz
Publicado por: Yoldy en 9 Mayo 2017, 03:06 am
Hola, necesito de su ayuda, quiero imprimir pares de caracteres para toda la tabla, de forma aleatoria.

como

? # ¡ x
x ? # ¡
0 - + *
+ 0 - *

Código
  1. #include <stdio.h>
  2. #include <stdlib.h> //incluye srand() y rand()
  3. #include <conio.h>
  4. #include <time.h> //incluye time()
  5.  
  6. char a[4][4]; //tamaño de la matriz
  7. char cartas[]={'#','%','@','*','!','<','x'};
  8. int total=sizeof(cartas);
  9.  
  10. int main()
  11. {
  12.    srand(time(0));//numeros Aleatorios en funcion del tiempo
  13.    for (int i=0;i<4;i++)//para desplazarse por las columnas
  14.    {
  15.        for (int j=0;j<4;j++)//para desplazarse por las filas
  16.        {
  17.            a[i][j]=cartas[rand()%total];
  18.            printf("\t%c",a[i][j]);//imprime elemento de la matriz en pantalla
  19.        }
  20.      printf("\n\n");
  21.    }
  22.   getchar();
  23. }
  24.  


Título: Re: Llenado de Matriz
Publicado por: engel lex en 9 Mayo 2017, 03:20 am
mi recomendación es que hagas otro array que reciba las 2 elementos que quieres usar...


tambien puede reorganizar tu array y solo usas los 2 primeros


Título: Re: Llenado de Matriz
Publicado por: MAFUS en 9 Mayo 2017, 09:28 am
No entiendo la pregunta.
¿Quieres encontrar dos caracteres iguales que haya en la tabla?


Título: Re: Llenado de Matriz
Publicado por: Yoldy en 9 Mayo 2017, 12:22 pm
OK, me refiero a que quiero mostrar pares de caracteres para llenar mi tabla, de forma aleatoria.


Título: Re: Llenado de Matriz
Publicado por: engel lex en 9 Mayo 2017, 12:33 pm
OK, me refiero a que quiero mostrar pares de caracteres para llenar mi tabla, de forma aleatoria.


Código:
? # ¡ x
x ? # ¡
0 - + *
+ 0 - *

no entiendo lo de pares... ya te perdí.... ahí no veo los pares aclarados ni nada...


Título: Re: Llenado de Matriz
Publicado por: MAFUS en 9 Mayo 2017, 15:19 pm
Ya entiendo, creo. La tabla debe tener dos unidades del mismo carácter en cualquier posición. Es decir: habrá un número tal de caracteres diferentes como la mitad de casillas de dicha tabla.
Pues deberás encontrar una forma de marcar los caracteres que han salido dos veces, para no incluirlos más.
Para darte ideas: usar una estructura que guarde el carácter y cuantas veces ha salido; usar un array adicional con correspondencia al de caracteres que indique cuantas veces ha salido un carácter; usar una lista enlazada donde se eliminen los caracteres que han salido dos veces.



Título: Re: Llenado de Matriz
Publicado por: CalgaryCorpus en 9 Mayo 2017, 17:03 pm
Al arreglo cartas le falta 1 elemento, la matriz de 4x4 = 16 caracteres, y cartas tiene tamano 7.

Una idea alternativa es que modifiques el arreglo de cartas, eligiendo aleatoriamente desde el, y llevando al final o al inicio la carta elegida, y recorrerlo 2 veces. Con eso, no requieres memoria adicional, ninguna estructura de datos extra, y llevar donde vas en 1 indice adicional.


Título: Re: Llenado de Matriz
Publicado por: MAFUS en 9 Mayo 2017, 17:36 pm
¿Podrías hacer un ejemplo de eso?


Título: Re: Llenado de Matriz
Publicado por: CalgaryCorpus en 9 Mayo 2017, 23:02 pm
O(1) espacio
O(n) operaciones, n el tamaño del arreglo de cartas, la mitad de la matriz

Verlo ejecutándose aquí: http://goo.gl/KLHE8S

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4.  
  5. char a[4][4];
  6. char cartas[] = {'#','%','@','*','!','<','x', '+'};
  7. int total=sizeof(cartas);
  8.  
  9. int main()
  10. {
  11.    int mover_a = total*2-1;
  12.    srand(time(0));
  13.    for (int i=0; i < 4; i++) {
  14.        for (int j=0; j < 4; j++) {
  15.            int hacia = mover_a % total;
  16.            int desde = rand() % (hacia + 1);
  17.  
  18.            a[i][j] = cartas[desde];
  19.            cartas[desde] = cartas[hacia];
  20.            cartas[hacia] = a[i][j];
  21.  
  22.            printf("\t%c ",a[i][j]);
  23.  
  24.            mover_a--;
  25.        }
  26.      printf("\n\n");
  27.    }
  28. }
  29.  


Título: Re: Llenado de Matriz
Publicado por: MAFUS en 9 Mayo 2017, 23:36 pm
Entiendo y es interesante. El array cambia en cada iteración, es muy aleatorio.
Aunque el segundo elemento del par solo puede volver a salir cuando han terminado de salir todos los símbolos, nunca podría generarse un patrón como el del ejemplo del enunciado.
Aunque, ahora que lo veo, los dos estamos equivocados XD


Título: Re: Matriz
Publicado por: CalgaryCorpus en 10 Mayo 2017, 03:00 am
Es completamente posible que aparezca en la salida un patron como el del enunciado.
Hay que cambiar el arreglo de cartas para que incluya el "?" y sacar la "x" que puse yo sin fijarme.


Título: Re: Matriz
Publicado por: MAFUS en 10 Mayo 2017, 07:15 am
No es por eso. En el ejemplo se toman los 4 primeros símbolos y se sitúan aleatoriamente en la primera línea. En la segunda línea se sitúan de nuevo los mismos símbolos pero con otra disposición. Después,  ya en la tercera línea se usa un juego de símbolos diferentes y se actúa como en el casp anterior.

En tu código se disponen los ocho signos a la ves y no vuelven a repetirse hasta que no hayan salido todos.

En verdad la solución es muy parecida a la que propones solo que hay que hacerlo a medio array de símbolos cada vez.


Título: Re: Matriz
Publicado por: CalgaryCorpus en 12 Mayo 2017, 11:52 am
Solo por jugar, para poder repetir los valores antes de llegar al final del arreglo cartas, se puede hacer un truco: usar la matriz final como memoria adicional y aplicar la misma idea anterior, e.g.: http://goo.gl/mOF4jJ

Aun no es como lo descrito, pero la idea se puede aplicar de multiples formas para evitar o forzar repeticiones, sin requerir de estructuras de datos adicionales o contar, la solucion funciona por construccion, como se demuestra en el codigo del link, el que copio aqui:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4.  
  5. char a[4][4];
  6. char cartas[] = {'#','%','@','*','!','<','?', '+'};
  7. int total=sizeof(cartas);
  8.  
  9. int main()
  10. {
  11.    for(int i = 0; i < total*2; i++) {
  12.        a[i/4][i%4] = cartas[i%8];
  13.    }
  14.  
  15.    srand(time(0));
  16.    for (int mover_a = total*2-1; mover_a >=0; mover_a--) {
  17.        int hacia = mover_a;
  18.        int desde = rand() % (hacia + 1);
  19.  
  20.        char temp = a[hacia/4][hacia%4];
  21.        a[hacia/4][hacia%4] = a[desde/4][desde%4];
  22.        a[desde/4][desde%4] = temp;
  23.  
  24.        printf("\t%c ",a[hacia/4][hacia%4]);
  25.        if(mover_a%4 == 0) printf("\n");
  26.  
  27.   }
  28.   printf("\n\n");
  29. }

Verlo ejecutando aqui; http://goo.gl/mOF4jJ


Título: Re: Matriz
Publicado por: MAFUS en 12 Mayo 2017, 17:00 pm
Yo decía algo más así:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4.  
  5. char cartas[] = {'#', '%', '@', '*', '!', '<', 'x', '+'};
  6. int total = sizeof(cartas);
  7.  
  8. int main() {
  9.    int inicio = 0;
  10.  
  11.    srand(time(NULL));
  12.  
  13.    for (int mitad=0; mitad<2; ++mitad) {
  14.        for (int i=0; i<2; ++i) {
  15.            int longitud = total/2;
  16.  
  17.            for (int j=0; j<4; ++j) {
  18.                int deja = longitud - 1 + inicio;;
  19.                int pilla;
  20.  
  21.                do {
  22.                    pilla = rand() % longitud + inicio;
  23.                } while(j < 3 && pilla == deja);
  24.  
  25.                printf(" %c", cartas[pilla]);
  26.  
  27.                char x = cartas[deja];
  28.                cartas[deja] = cartas[pilla];
  29.                cartas[pilla] = x;
  30.                --longitud;
  31.            }
  32.            puts("");
  33.        }
  34.        inicio = total/2;
  35.    }
  36. }

Como puedes ver me he basado en tu idea.

Éste es el resultado:
Código:
# * @ %
@ % * #
! < + x
x + ! <
La primera fila y la segunda usan un conjunto de símbolo.
La tercera y la cuarta usan otro.


Título: Re: Matriz
Publicado por: CalgaryCorpus en 12 Mayo 2017, 22:14 pm
Super bueno.

Le falta la aritmetica para los indices de la matriz (y llenarla).
Sin embargo, agregarla diluye la magia de la simplicidad inicial.