PI-ITBA / 2024_02

Consultas 2C 2024
4 stars 0 forks source link

piersADT #174

Open bleite12 opened 5 days ago

bleite12 commented 5 days ago

Hola, hice este ejercicio del parcial del cuatrimestre pasado, me corre los asserts pero no se si esta bien como hice la estructura, me parece que es poco eficiente crear el vector de puertos sin saber si voy a usar todos. lo habia hecho con una lista de puertos y los ordenaba con la funcion compare como los muelles pero tampoco estaba seguro. Agradeceria si alguien me puede corregir la estructura y la eficiencia.

#include "ej2.h"
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>

typedef struct puertos * Tpuertos;
typedef struct piersCDT{
    Tpuertos puertos;
    int   DimPuertos;
}piersCDT;

typedef struct muelles * Tmuelles;
typedef struct muelles{
    Tmuelles next;
    int NumMuelle;
    int BarcoSIoNO;
}muelles;

typedef struct puertos{
    int NumPuerto;
    int dimMuelles;
    int dimMuellesOccupied;
    Tmuelles muellesFirst;
}puertos;

Tpuertos addPierRec(Tpuertos puerto, int nuevoPuerto, int * ok);
int compare(int n1, int n2);
Tmuelles addMuelleRec(Tmuelles muelle, int dockNumber, int * ok);
int shipInDockRec(Tmuelles muelle, int dockNumber);
int DockShipRec(Tmuelles muelle, int dockNumber, int * ok);
int undockShipRec(Tmuelles muelle, int NumMuelle);

int compare(int n1, int n2){
    if(n1 == n2){return 0;}
    if(n1 > n2){return 1;}
    return -1;

}
piersADT newPiers(void){
    piersADT new  = calloc(1, sizeof(struct piersCDT));
    return new;
} 

int addPier(piersADT piers, int pierNumber) {
    if (pierNumber <= 0) {
        return 0; // Número de puerto inválido
    }

    // Verifica si el puerto ya existe recorriendo el vector actual
    for (int i = 0; i < piers->DimPuertos; i++) {
        if (piers->puertos[i].NumPuerto == pierNumber) {
            return 0; // El puerto ya existe
        }
    }

    // Expande el vector de puertos si es necesario
    if (pierNumber > piers->DimPuertos) {
        piers->puertos = realloc(piers->puertos, pierNumber * sizeof(struct puertos));

        // Inicializa los nuevos elementos del vector
        for (int i = piers->DimPuertos; i < pierNumber; i++) {
            piers->puertos[i].NumPuerto = 0;
            piers->puertos[i].dimMuelles = 0;
            piers->puertos[i].dimMuellesOccupied = 0;
            piers->puertos[i].muellesFirst = NULL; // Inicializa la lista de muelles como NULL
        }

        piers->DimPuertos = pierNumber;
    }

    // Asigna el número de puerto en la posición correspondiente
    piers->puertos[pierNumber - 1].NumPuerto = pierNumber;
    return 1; // Se agregó exitosamente el nuevo puerto
}

int addPierDock(piersADT piers, int pierNumber, int dockNumber){

    //tengo que buscar el pier.
    int ok = 0;
        if(piers->puertos[pierNumber-1].NumPuerto == pierNumber){
            // entro a la recursiva, y levanto un flag.
            piers->puertos[pierNumber-1].muellesFirst = addMuelleRec(piers->puertos[pierNumber-1].muellesFirst, dockNumber, &ok);
            piers->puertos[pierNumber-1].dimMuelles++;
            return (ok == 1);
        }

    return 0; // solo llega aca si el muelle no existe.

}

Tmuelles addMuelleRec(Tmuelles muelle, int dockNumber, int * ok){
    if(muelle == NULL || compare(muelle->NumMuelle, dockNumber) > 0){
        // lo agrego, levanto el flag.
        *ok = 1;
        Tmuelles new = calloc(1, sizeof(struct muelles));
        new->next = muelle;
        new->NumMuelle = dockNumber;
        return new;
    }

    if(compare(muelle->NumMuelle, dockNumber) == 0){
        return muelle;
    }

    muelle->next = addMuelleRec(muelle->next, dockNumber, ok);
    return muelle;
}

int dockShip(piersADT piers, int pierNumber, int dockNumber){
    int ok = 0;

        if(piers->puertos[pierNumber-1].NumPuerto == pierNumber){
            if(DockShipRec(piers->puertos[pierNumber-1].muellesFirst, dockNumber, &ok)){
                piers->puertos[pierNumber-1].dimMuellesOccupied += ok;
                return 1;
            }
            return 0;
        }

    return 0; // solo llega aca si el muelle no existe.
}

int DockShipRec(Tmuelles muelle, int dockNumber, int * ok){
    if(muelle == NULL){
        return 0;
    }

    if(muelle->NumMuelle == dockNumber){
        if(muelle->BarcoSIoNO == 0){
            muelle->BarcoSIoNO = 1;
            *ok = 1;
            return 1;
        }
        return 0;
    }

    return DockShipRec(muelle->next, dockNumber, ok);

}

int shipInDock(const piersADT piers, int pierNumber, int dockNumber){

    if(piers->puertos[pierNumber-1].NumPuerto == pierNumber){
            return shipInDockRec(piers->puertos[pierNumber-1].muellesFirst, dockNumber);
    }

    return 0; // solo llega aca si el muelle no existe.
}

int shipInDockRec(Tmuelles muelle, int dockNumber){
    if(muelle == NULL){
        return 0;
    }

    if(muelle->NumMuelle == dockNumber){
        return (muelle->BarcoSIoNO == 1);
    }

    return shipInDockRec(muelle->next, dockNumber);

}

int pierShips(const piersADT piers, int pierNumber){

    if(piers->puertos[pierNumber-1].NumPuerto == pierNumber){
        return piers->puertos[pierNumber-1].dimMuellesOccupied;
    }
    return -1; // no existe el puerto.
}

int undockShip(piersADT piers, int pierNumber, int dockNumber){

    if(piers->puertos[pierNumber-1].NumPuerto == pierNumber){
            //aca busco el muelle.
        if(undockShipRec(piers->puertos[pierNumber-1].muellesFirst, dockNumber) == 1){
            piers->puertos[pierNumber-1].dimMuellesOccupied--;
            return 1;
        }else{
            return 0;
        }
    }

    return 0; // entonces no existe el puerto.
}

int undockShipRec(Tmuelles muelle, int NumMuelle){
    if(muelle == NULL || NumMuelle < muelle->NumMuelle){
        return 0;
    }

    if(NumMuelle == muelle->NumMuelle){
        if(muelle->BarcoSIoNO == 0){
            return 0;
        }
        muelle->BarcoSIoNO = 0;
        return 1;

    }
    return undockShipRec(muelle->next, NumMuelle);
}

void freePiers(piersADT piers) {
    if (piers == NULL) {
        return; // No hay nada que liberar si es NULL
    }

    // Recorre el vector de puertos y libera cada puerto y sus muelles
    for (int i = 0; i < piers->DimPuertos; i++) {

        Tmuelles currentMuelle = piers->puertos[i].muellesFirst;

        while (currentMuelle != NULL) {
            Tmuelles toFree = currentMuelle;
            currentMuelle = currentMuelle->next;
            free(toFree); // Libera cada muelle
        }

    }
    // Libera el vector de puertos
    free(piers->puertos);
    // Libera la estructura de piers
    free(piers);
}

.h

typedef struct piersCDT * piersADT;
/*
 Crea un sistema de administración de muelles de los puertos de una ciudad
*/

piersADT newPiers(void);
/* Agrega el puerto #pierNumber y retorna 1
* Falla si el puerto ya existe y retorna 0
* Un puerto inicia sin muelles. Se asume un bajo porcentaje de puertos libres
*/
int addPier(piersADT piers, int pierNumber);
/* Agrega el muelle #dockNumber al puerto #pierNumber y retorna 1
* Falla si el muelle ya existe en el puerto o si el puerto no existe y retorna 0
* Un muelle inicia sin una embaración amarrada
* Se asume un bajo porcentaje de muelles libres para cada puerto
*/
int addPierDock(piersADT piers, int pierNumber, int dockNumber);
/* Amarra una embaración en el muelle #dockNumber del puerto #pierNumber y retorna 1
* Falla si el muelle ya estaba ocupado o si el muelle no existe en el puerto
* o si el puerto no existe y retorna 0
*/
int dockShip(piersADT piers, int pierNumber, int dockNumber);
/* Indica si hay una embarcación amarrada en el muelle #dockNumber del puerto #pierNumber
* Retorna:
* 1 si hay una embarcación amarrada
* 0 si no hay una embaración amarrada
* -1 si el muelle no existe en el puerto o si el puerto no existe
*/
int shipInDock(const piersADT piers, int pierNumber, int dockNumber);
/* Indica la cantidad de embarcaciones amarradas en todos los muelles del puerto
* #pierNumber
* Falla si el puerto no existe y retorna -1
*/
int pierShips(const piersADT piers, int pierNumber);
/* Desamarra una embaración en el muelle #dockNumber del puerto #pierNumber y retorna 1
* Falla si el muelle estaba libre o si el muelle no existe en el puerto
* o si el puerto no existe y retorna 0
*/
int undockShip(piersADT piers, int pierNumber, int dockNumber);
/* Libera los recursos utilizados por el TAD
*/
void freePiers(piersADT piers);
marcelogarberoglio commented 5 days ago

El enunciado pide "que las funciones addPierDock, dockShip, shipInDock, pierShips y undockShip puedan ser implementadas de la forma más eficiente posible " por lo tanto lo correcto es hacer vectores,, para poder acceder ditectamente por número de puerto. Entonces si bien acertaste en usar vectores, no lo estás usando en forma adecuada, por ejemplo en addPier hacés

  // Verifica si el puerto ya existe recorriendo el vector actual
    for (int i = 0; i < piers->DimPuertos; i++) {
        if (piers->puertos[i].NumPuerto == pierNumber) {
            return 0; // El puerto ya existe
        }
    }

y la idea es que no guardes NumPuerto sino que vayas directo a la posición de pierNumber, y de alguna manera saber si está ocupada o no.

bleite12 commented 5 days ago

entonces seria un vector de punteros a puertos y si apunta a NULL es que esta vacio?

marcelogarberoglio commented 5 days ago

Puede ser, o que en cada puerto tengas la cantidad de muelles, y si la cantidad es cero es que está vacío. Más allá de eso lo importante es que accedas directamente por número de puerto, y luego directamente por número de muelle.

bleite12 commented 5 days ago

creo que ahora esta mejor.

typedef struct puertos * Tpuertos;
typedef struct piersCDT{
    Tpuertos * puertos;
    int   DimPuertos;
}piersCDT;

typedef struct muelles * Tmuelles;
typedef struct muelles{
    Tmuelles next;
    int NumMuelle;
    int BarcoSIoNO;
}muelles;

typedef struct puertos{
    int dimMuelles;
    int dimMuellesOccupied;
    Tmuelles muellesFirst;
}puertos;

Tpuertos addPierRec(Tpuertos puerto, int nuevoPuerto, int * ok);
int compare(int n1, int n2);
Tmuelles addMuelleRec(Tmuelles muelle, int dockNumber, int * ok);
int shipInDockRec(Tmuelles muelle, int dockNumber);
int DockShipRec(Tmuelles muelle, int dockNumber, int * ok);
int undockShipRec(Tmuelles muelle, int NumMuelle);

int compare(int n1, int n2){
    if(n1 == n2){return 0;}
    if(n1 > n2){return 1;}
    return -1;

}
piersADT newPiers(void){
    piersADT new  = calloc(1, sizeof(struct piersCDT));
    return new;
} 

int addPier(piersADT piers, int pierNumber) {

    // Expande el vector de punteros a Tpuertos si es necesario
    if (pierNumber > piers->DimPuertos) {
        piers->puertos = realloc(piers->puertos, pierNumber * sizeof(Tpuertos));

        // Inicializa los nuevos elementos del vector a NULL
        for (int i = piers->DimPuertos; i < pierNumber; i++) {
            piers->puertos[i] = NULL; // Apunta a NULL
        }

        piers->DimPuertos = pierNumber;
    }

    // Verifica si el puerto ya existe recorriendo el vector actual
    if (piers->puertos[pierNumber-1] != NULL) {
        return 0; // El puerto ya existe
    }

    // Asigna el número de puerto en la posición correspondiente
    piers->puertos[pierNumber - 1] = calloc(1, sizeof(puertos));
    return 1; // Se agregó exitosamente el nuevo puerto
}

int addPierDock(piersADT piers, int pierNumber, int dockNumber){

    int ok = 0;
        if(piers->puertos[pierNumber-1] != NULL){
            // entro a la recursiva, y levanto un flag.
            piers->puertos[pierNumber-1]->muellesFirst = addMuelleRec(piers->puertos[pierNumber-1]->muellesFirst, dockNumber, &ok);
            piers->puertos[pierNumber-1]->dimMuelles++;
            return (ok == 1);
        }

    return 0; // solo llega aca si el muelle no existe.

}

Tmuelles addMuelleRec(Tmuelles muelle, int dockNumber, int * ok){
    if(muelle == NULL || compare(muelle->NumMuelle, dockNumber) > 0){
        // lo agrego, levanto el flag.
        *ok = 1;
        Tmuelles new = calloc(1, sizeof(struct muelles));
        new->next = muelle;
        new->NumMuelle = dockNumber;
        return new;
    }

    if(compare(muelle->NumMuelle, dockNumber) == 0){
        return muelle;
    }

    muelle->next = addMuelleRec(muelle->next, dockNumber, ok);
    return muelle;
}

int dockShip(piersADT piers, int pierNumber, int dockNumber){
    int ok = 0;

        if(piers->puertos[pierNumber-1] != NULL){
            if(DockShipRec(piers->puertos[pierNumber-1]->muellesFirst, dockNumber, &ok)){
                piers->puertos[pierNumber-1]->dimMuellesOccupied += ok;
                return 1;
            }
            return 0;
        }

    return 0; // solo llega aca si el muelle no existe.
}

int DockShipRec(Tmuelles muelle, int dockNumber, int * ok){
    if(muelle == NULL){
        return 0;
    }

    if(muelle->NumMuelle == dockNumber){
        if(muelle->BarcoSIoNO == 0){
            muelle->BarcoSIoNO = 1;
            *ok = 1;
            return 1;
        }
        return 0;
    }

    return DockShipRec(muelle->next, dockNumber, ok);

}

int shipInDock(const piersADT piers, int pierNumber, int dockNumber){

    if(piers->puertos[pierNumber-1] != NULL){
            return shipInDockRec(piers->puertos[pierNumber-1]->muellesFirst, dockNumber);
    }

    return 0; // solo llega aca si el muelle no existe.
}

int shipInDockRec(Tmuelles muelle, int dockNumber){
    if(muelle == NULL){
        return 0;
    }

    if(muelle->NumMuelle == dockNumber){
        return (muelle->BarcoSIoNO == 1);
    }

    return shipInDockRec(muelle->next, dockNumber);

}

int pierShips(const piersADT piers, int pierNumber){

    if(piers->puertos[pierNumber-1] != NULL){
        return piers->puertos[pierNumber-1]->dimMuellesOccupied;
    }
    return -1; // no existe el puerto.
}

int undockShip(piersADT piers, int pierNumber, int dockNumber){

    if(piers->puertos[pierNumber-1]  !=  NULL){
            //aca busco el muelle.
        if(undockShipRec(piers->puertos[pierNumber-1]->muellesFirst, dockNumber) == 1){
            piers->puertos[pierNumber-1]->dimMuellesOccupied--;
            return 1;
        }else{
            return 0;
        }
    }

    return 0; // entonces no existe el puerto.
}

int undockShipRec(Tmuelles muelle, int NumMuelle){
    if(muelle == NULL || NumMuelle < muelle->NumMuelle){
        return 0;
    }

    if(NumMuelle == muelle->NumMuelle){
        if(muelle->BarcoSIoNO == 0){
            return 0;
        }
        muelle->BarcoSIoNO = 0;
        return 1;

    }
    return undockShipRec(muelle->next, NumMuelle);
}

void freePiers(piersADT piers) {
    if (piers == NULL) {
        return; // No hay nada que liberar si es NULL
    }

    // Recorre el vector de puertos y libera cada puerto y sus muelles
    for (int i = 0; i < piers->DimPuertos; i++) {
        if (piers->puertos[i] != NULL) { // Verifica si el puerto existe
            Tmuelles currentMuelle = piers->puertos[i]->muellesFirst;

            // Libera la lista de muelles
            while (currentMuelle != NULL) {
                Tmuelles toFree = currentMuelle;
                currentMuelle = currentMuelle->next;
                free(toFree); // Libera cada muelle
            }

            // Libera el puerto
            free(piers->puertos[i]);
        }
    }

    // Libera el vector de punteros a puertos
    free(piers->puertos);

    // libera el puntero al vector.?
    free(piers);
}
marcelogarberoglio commented 5 days ago

Está mejor, para que esté del todo bien tendrías que hacer con los muelles lo mismo que los puertos.m Te tiene que quedar un vector de vectores, como el de las ardillas.