PI-ITBA / 2024_01

8 stars 0 forks source link

TP8_EJ7 #181

Closed JaimeNazar closed 4 months ago

JaimeNazar commented 5 months ago

Hola, buenas tardes, escribo para consultar la resolucion del Ejercicio 7 de la Guia 8, en particular si tiene buen estilo.

Muchas gracias.

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

#define COLS 7
#define FILS 6

#define BLOQUE 10
#define DIREC 8

typedef enum {DER=0, IZQ, ABA, ARR, I_AR, I_AB, D_AR, D_AB } Tdireccion;
typedef char sopa[FILS][COLS];

struct posicion {
    char * palabra;
    size_t fila;
    size_t columna;
    Tdireccion direccion;
};

struct posicion * resolverSopa(sopa s, char ** dicc);
struct posicion buscarPalabraDir(sopa s, char * pal, Tdireccion dir, int fila, int col);
void agregarPalabra(struct posicion ** vec, int * dim, struct posicion pal);

int main(void) {
  char * diccionario[] = {"ARRE", "CANCION", "CAPA", "ERROR", "ORCO", "PERRO", "PERTINAZ", "REA", "RIO", ""};

  sopa s =
     {{'X','X','X','O','X','X','X'},
      {'A','P','A','C','Y','Y','O'},
      {'Z','E','Z','R','Z','C','X'},
      {'E','R','R','O','R','X','X'},
      {'X','R','I','O','I','E','X'},
      {'X','O','X','X','O','X','X'}};

    struct posicion * res = resolverSopa(s, diccionario);
    // La cantidad de palabras encontradas debe ser 9
    int expected = 9;
    int count = 0;

    while ( res[count].palabra != NULL)
        printf("%s\n", res[count++].palabra);

    printf("Expected: %d\nFound: %d\n", expected, count);

    assert(strcmp(res[0].palabra,"ARRE")==0);
    assert(res[0].fila==1);
    assert(res[0].columna==2);
    assert(res[0].direccion==D_AB);

    assert(strcmp(res[3].palabra,"ORCO")==0);
    assert(res[3].fila==3);
    assert(res[3].columna==3);
    printf("%d\n", res[3].direccion);
    assert(res[3].direccion==ARR);

    assert(strcmp(res[4].palabra,"ORCO")==0);
    assert(res[4].fila==4);
    assert(res[4].columna==3);
    assert(res[4].direccion==D_AR);

    assert(strcmp(res[6].palabra,"REA")==0);
    assert(res[6].fila==3);
    assert(res[6].columna==2);
    assert(res[6].direccion==I_AR);

    puts("OK");

    free(res);
    return 0;
}

struct posicion * resolverSopa(sopa s, char ** dicc)
{
    int dim = 0;
    struct posicion * vec = NULL;
    struct posicion aux;

    for(int p = 0; dicc[p][0] != '\0'; p++)                          // Pasar por todas las palabras
    {
        for(int i = 0; i < FILS; i++)
        {
            for(int j = 0; j < COLS; j++)
            {
                for(int k = 0; k < DIREC; k++)                  // Buscar en todas las direcciones
                {
                    aux = buscarPalabraDir(s, dicc[p], k, i, j);

                    if (aux.palabra != NULL)
                    {
                        agregarPalabra(&vec, &dim, aux);
                    }
                }
            }
        }

    }

    if (vec != NULL)
        vec[dim].palabra = NULL;

    return vec;
}

struct posicion buscarPalabraDir(sopa s, char * pal, Tdireccion dir, int fila, int col)
{
    int enc = 0;
    int i   = fila;
    int j   = col;

    struct posicion p;
    p.palabra = NULL;

    while(i < FILS && i >= 0 && j < COLS && j >= 0)
    {
        if (pal[enc++] != s[i][j])
        {
            return p;        // Volve da empezar
        }

        if(pal[enc] == '\0')
        {
            enc = 0;

            p.palabra = pal;
            p.fila = fila;
            p.columna = col;
            p.direccion = dir;

            return p;
        }

        switch(dir)
        {
            case DER: 
                j++;
                break;
            case IZQ:
                j--;
                break;
            case ABA: 
                i++;
                break;
            case ARR: 
                i--;
                break;
            case I_AR: 
                i--;
                j--;
                break;
            case I_AB:
                i++;
                j--;
                break;
            case D_AR:
                i--;
                j++;
                break;
            case D_AB:
                i++;
                j++;
                break;
            default:
            break;
        };

    }

    return p;
}

void agregarPalabra(struct posicion ** vec, int * dim, struct posicion pal)
{
    if ((*dim) % BLOQUE == 0)
    {
        *vec = realloc(*vec, ((*dim) + BLOQUE) * sizeof(struct posicion));
    }
    (*vec)[(*dim)++] = pal;
}
marcelogarberoglio commented 5 months ago

resolverSopa: como que cuatro for anidados suena confuso, se podría modularizar un poco, por ejemplo que por cada palabra llame a una función que la busque en la matriz

En vez de que agregarpalabra reciba el doble puntero se podría hacer que retorne el nuevo vector (o el mismo si no cambió), o sea

struct posicion * agregarPalabra(struct posicion * vec, int * dim, struct posicion pal)
{
    if ((*dim) % BLOQUE == 0)
    {
        vec = realloc(vec, ((*dim) + BLOQUE) * sizeof(struct posicion));
    }
    vec[(*dim)++] = pal;
    return vec;
}

y como alternativa al switch de buscarPalabraDir vieron en el taller y en la solución al ej 2 del parcial cómo usar un vector de movimientos. La función podría recibir cuánto incrementar j y cuánto i.