Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: amgarciac en 19 Agosto 2013, 15:56 pm



Título: Sopa de letras que recorra una matriz de direcciones
Publicado por: amgarciac en 19 Agosto 2013, 15:56 pm
Buenas tardes, me gustaría saber cómo podría hacer una sopa de letras que recorra una matriz de direcciones sabiendo que la palabra a buscar es una sola (en todas las direcciones posibles): "OIE". Me gustaría elaborarlo como el siguiente, pero no entiendo el código, es decir, la forma de hacerlo: http://foro.elhacker.net/programacion_cc/sopa_de_letras_respuesta_erronea-t286627.0.html;msg1417535#msg1417535 (http://foro.elhacker.net/programacion_cc/sopa_de_letras_respuesta_erronea-t286627.0.html;msg1417535#msg1417535)

Así que os agraderceía enormemente cualquier ayuda.

Un saludo.


Título: Re: Cómo programar una sopa de letras basada en matrices de direcciones
Publicado por: Alien-Z en 19 Agosto 2013, 16:20 pm
¿Las salidas son correctas y te da error?: Problema de eficiencia (los jueces online te suelen exigir que los programas se ejecuten en un determinado tiempo), no has seguido las instrucciones de entrada/salida que te indican en la web (el Juez es un programa y tiene implementado un método para leer e imprimir que hay que seguir a rajatabla o no te comprende), etc.

En el link que has añadido te explican que debes comparar letra por letra según la entrada. Te hago un esquema en pseudocódigo:

Código:
SI (i+2 no nos salimos de la cadena) Y (cadena[i] == 'O') Y (cadena[i+1] == 'I') Y (cadena[i+2] == 'E') -> contador++;
i++;

Empieza horizontalmente línea por línea de izquierda a derecha y viceversa hasta el final de la entrada; después lo mismo pero verticalmente y por último en diagonal.

Si no funciona ayudaría que indicaras cuál es exactamente el error que te señala el juez online. Un saludo.


Título: Re: Cómo programar una sopa de letras basada en matrices de direcciones
Publicado por: amgarciac en 19 Agosto 2013, 16:29 pm
Disculpe pero el link al que me refería no era ese (había corregido mal el hipervínculo, pq había olvidado cambiar la URL), sino este: http://foro.elhacker.net/programacion_cc/sopa_de_letras_respuesta_erronea-t286627.0.html;msg1417535#msg1417535 (http://foro.elhacker.net/programacion_cc/sopa_de_letras_respuesta_erronea-t286627.0.html;msg1417535#msg1417535).

Si observas la respuesta, se juega con una matriz de direcciones, la cual no entiendo en cuanto a los números (0,-1,1) tal y como se colocan para hacer posiciones (digo yo).

Así, que lo que quiero es que me lo expliques con matrices, única manera aceptada. Que con comparaciones sin más ya lo he efectuado de "mil maneras", algo que explicaban en el link que te había puesto al principio equívocamente (el de hispabyte).


Título: Re: Cómo programar una sopa de letras basada en matrices de direcciones
Publicado por: do-while en 19 Agosto 2013, 18:45 pm
¡Buenas!

Olvídate del tema de la OIE, de la UVA o de cualquier otro juez online. Hay problemas en los que por mucho que cambies el formato de salida (muchas veces la causa del error es esta), aunque esta sea correcta te dan errores de respuesta incorrecta.

Hace mucho que los mandé a freír espárragos...

¡Saludos!


Título: Re: Cómo programar una sopa de letras basada en matrices de direcciones
Publicado por: amgarciac en 19 Agosto 2013, 18:57 pm
Lo sé, pero quiero comprender la solución de matrices del enlace anterior, que es la única que me ha admitido; mejor dicho, comprender el código para futuras ocasiones pues es la 1ª vez que me enfrento a una matriz de direcciones.

Que por el juez da igual, pues estando bien las salidas de prueba me conformo, y que el de la OIE es tan superestricto que no sé ni lo que decir.

Así que si supieses como va ese código, explícamelo, por favor. Te lo agradecería.


Título: Re: Sopa de letras que recorra una matriz de direcciones
Publicado por: ghastlyX en 23 Agosto 2013, 04:19 am
Primero de todo, lo siento. Todo este tema ha sido porque mi código (precioso, por cierto xDD) no se ha entendido.

A ver, no es que el problema se tenga que hacer con matrices de direcciones, si lo haces BIEN con ifos te entrará, el problema es que el código a base de ifos es generalmente horrible, largo y casi siempre sale un bug.

El código mío en sí es muy simple, sólo que si nunca has visto la idea se hace rara. Hay 8 direcciones posibles para que una palabra aparezca, así que para cada dirección, me creo dos arrays de tamaño 3 con los incrementos de fila y de columna asociados a cada posición en dicha dirección. Para simplificar el código, estos arrays los meto en dos arrays, uno para la fila o y otro para las columnas. De esta manera puedo iterar de manera genérica sobre todas las direcciones con un simple for.

Sé que en el foro los concursos de programación algorítmica y los jueces online son en general bastante odiados, pero he de romper una lanza en su favor xDD. Primero decir que aunque un programa que enviéis de Wrong Answer y a vosotros os vaya bien con los ejemplos que probáis, el error va a ser vuestro, no del juez. Aparte de los casos públicos que se dan en los problemas, los jueces utilizan múltiples casos de prueba privados, buscados especialmente para cazar los errores que el código pueda tener.

Y además de ser divertidos, en estos concursos y jueces se aprende mucho: primero algoritmia y segundo a pensar de manera totalmente abstracta, cosa muy útil para resolver otros tipos de problemas. Además, si se os da bien y se obtienen buenos resultados en concursos, las empresas grandes suelen envíar ofertas de trabajo y cuando digo grandes me refiero a tales como Google o Facebook.


Título: Re: Sopa de letras que recorra una matriz de direcciones
Publicado por: amgarciac en 23 Agosto 2013, 20:17 pm
Muchas gracias por su respuesta, aunque al final ya había logrado entender el código comprendiendo la relación filas-columnas con los arrays.

Respecto al planteamiento en base a estructuras condicionales del problema, cierto que puede estar mal planteada según el juez, y sería el caso (si no me equivoco) por sobrepasarse en el análisis del cumplimiento de la condición de celdas inexsistentes.

Por último, me gustaría saber si para este mismo problema así como para otros similares, vamos, sopas de letras cualesquiera, bastaría con meter en las celdas números del -1 al 1, siendo los arrays unidimensionales.

Un saludo.
Buenas tardes.


Título: Re: Sopa de letras que recorra una matriz de direcciones
Publicado por: ghastlyX en 23 Agosto 2013, 20:32 pm
La verdad, no entiendo tu pregunta. No sé a qué te refieres con poner números del -1 al 1 en las celdas.


Título: Re: Sopa de letras que recorra una matriz de direcciones
Publicado por: amgarciac en 24 Agosto 2013, 18:56 pm
Me explicaré mejor. Quiero saber si esos dos arrays que almacenan direcciones, servirían si fuesen unidimensionales.


Título: Re: Sopa de letras que recorra una matriz de direcciones
Publicado por: ghastlyX en 24 Agosto 2013, 20:43 pm
Sí que puedes. Simplemente tendrías que poner un sólo valor por dirección, que sería el incremento inicial. Entonces desde el código, habría que mantener la suma acumulada en lugar de sumar directamente el valor como hago yo. Las dos maneras son igual de buenas y en un concurso yo haría esta opción, ya que no depende de la longitud de la string y el array es menos engorroso de crear. Hice la otra en aquel momento porque pensé que se entendería mejor el código.


Título: Re: Sopa de letras que recorra una matriz de direcciones
Publicado por: amgarciac en 26 Agosto 2013, 18:56 pm
Muchas gracias por la respuesta. Aprovecho para exponer cómo quedaría con array unidimensional:

Código:
#include <iostream>

#include <vector>

using namespace std;

int arrf[8] = { 0, -1, -1, -1, 0, 1, 1, 1 };
int arrc[8] = { -1, -1, 0, 1, 1, 1, 0, -1 };
char s [] = "OIE";

int main() {
int n, m;
while (cin >> n >> m) {
int res = 0;
vector<vector<char> > S(n, vector<char>(m));
for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) cin >> S[i][j];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
for (int d = 0; d < 8; ++d) {
bool trobat = true;
for (int h = 0; h < 3 && trobat; ++h) {
int f = i + h*arrf[d], c = j + h*arrc[d];
if (f < 0 || f >= n || c < 0 || c >= m || S[f][c] != s[h])
trobat = false;
}
if (trobat) res++;
}
}
}
cout << res << endl;
}
}

Saludos. Buenas noches