Ejercicio obligatorio 4

Fecha de entrega: Lunes 29 de mayo

Introducción

Mallas

../_images/20231_ej4.png

En computación una malla es una red de nodos y aristas que se puede utilizar para modelar diferentes problemas.

Los nodos son los puntos de esa malla. Cada nodo se identifica por un número. Además, los nodos tienen coordenadas de su posición y pueden tener propiedades adicionales.

Las aristas son los vértices que unen a los nodos de la malla. Cada arista se identifica, a su vez, por un número y se define a partir de los nodos que vincula. Al igual que los nodos, puede tener propiedades adicionales.

Archivo de malla

Se tiene un formato de mallas binario, con la siguiente estructura:

NN

N 0

N 1

...

N NN-1

NA

A 0

A 1

...

A NA-1

Es decir, el archivo comienza con NN, el número de nodos, el cual es un registro de tipo uint32_t, sigue con una sucesión de NN nodos, a continuación viene NA, el número de aristas, también de tipo uint32_t y finalmente una sucesión de NA aristas.

Los nodos tienen el siguiente formato:

x

y

masa

es_fijo

Donde los registros x, y son de tipo double, masa es de tipo float y es_fijo de tipo uint8_t y representa un booleano.

Las aristas tienen el siguiente formato:

Na

Nb

k

l

Donde Na y Nb son de tipo uint32_t y representan el índice de dos nodos y k y l son de tipo float.

Trabajo

Lectura

Implementar una función bool leer_numero_de_datos(FILE *f, size_t *numero); que reciba un archivo f abierto en modo lectura y devuelva en numero un número de aristas o de nodos. Por el nombre debe devolver true de haber funcionado correctamente. (Notar que, más allá de que en nuestro programa utilicemos el tipo size_t para abstraer las cantidades de elementos, no necesariamente sea el mismo tipo el que use el formato del archivo.)

Implementar una función bool leer_nodo(FILE *f, double *x, double *y, float *masa, bool *es_fijo); que reciba un archivo f y lea de él un nodo con sus propiedades. Debe devolver true en caso correcto.

Implementar una función bool leer_arista(FILE *f, uint32_t *na, uint32_t *nb, float *k, float *l); similar a las anteriores pero que lea las propiedades de una arista.

Escritura

Implementar una función bool escribir_numero_de_datos(FILE *f, size_t numero); que reciba un archivo f abierto en modo escritura y escriba en él un numero sea de aristas o de nodos. Por el nombre debe devolver true de haber funcionado correctamente.

Implementar una función bool escribir_nodo(FILE *f, double x, double y, float masa, bool es_fijo); que escriba un nodo.

Implementar una función bool escribir_arista(FILE *f, uint32_t na, uint32_t nb, float k, float l); que escriba una arista.

Aplicación

Escribir un programa que se ejecute como:

$ ./20231_ej4 entrada salida

que lea un archivo de entrada con el formato dado y en simultaneo vuelque su contenido por stdout y además lo escriba en salida con el mismo formato binario, haciendo uso de las funciones ya desarrolladas. Luego de ejecutado el programa, el archivo de salida deberá ser una copia exacta al de entrada.

Pruebas

Se provee un archivo 20231_ej4.bin el cual al pasar por la aplicación (además de la copia) debe generar por stdout la siguiente salida:

$ ./20231_ej4 20231_ej4.bin salida.bin
NN: 11
    N0: x: 13.423843, y: 8.074871, m: 10.000000, f: 0
    N1: x: 13.937092, y: 6.794693, m: 1.000000, f: 0
    N2: x: 12.467204, y: 6.970653, m: 1.000000, f: 0
    N3: x: 13.015529, y: 5.701709, m: 1.000000, f: 0
    N4: x: 11.612087, y: 5.685195, m: 1.000000, f: 0
    N5: x: 12.334441, y: 4.451064, m: 1.000000, f: 0
    N6: x: 10.962638, y: 4.252991, m: 1.000000, f: 0
    N7: x: 11.758088, y: 3.168708, m: 1.000000, f: 0
    N8: x: 10.334626, y: 2.776727, m: 1.000000, f: 0
    N9: x: 11.235344, y: 1.910100, m: 1.000000, f: 0
    N10: x: 9.997978, y: 0.999798, m: 1.000000, f: 1
NR: 19
    A0: na: 0, nb: 1, k: 100.000000, l: 1.379232
    A1: na: 1, nb: 2, k: 100.000000, l: 1.480382
    A2: na: 2, nb: 3, k: 100.000000, l: 1.382346
    A3: na: 3, nb: 4, k: 100.000000, l: 1.403539
    A4: na: 4, nb: 5, k: 100.000000, l: 1.429991
    A5: na: 5, nb: 6, k: 100.000000, l: 1.386028
    A6: na: 6, nb: 7, k: 100.000000, l: 1.344772
    A7: na: 7, nb: 8, k: 100.000000, l: 1.476446
    A8: na: 8, nb: 9, k: 100.000000, l: 1.249934
    A9: na: 9, nb: 10, k: 100.000000, l: 1.536140
    A10: na: 0, nb: 2, k: 100.000000, l: 1.460977
    A11: na: 2, nb: 4, k: 100.000000, l: 1.543900
    A12: na: 4, nb: 6, k: 100.000000, l: 1.572575
    A13: na: 6, nb: 8, k: 100.000000, l: 1.604292
    A14: na: 8, nb: 10, k: 100.000000, l: 1.808538
    A15: na: 1, nb: 3, k: 100.000000, l: 1.429648
    A16: na: 3, nb: 5, k: 100.000000, l: 1.424077
    A17: na: 5, nb: 7, k: 100.000000, l: 1.405923
    A18: na: 7, nb: 9, k: 100.000000, l: 1.362848
$

El archivo puede descargarse de acá 20231_ej4.bin

Nota

Para este trabajo no es necesario modularizar el problema, pero se recomienda hacerlo para practicar modularización y Makefile.

En el caso de modularizar en archivos entregar tanto los archivos como el Makefile que compila el proyecto.

Entrega

Deberá entregarse el código fuente del programa desarrollado o los fuentes y el Makefile en caso de haber modularizado.

El programa debe:

  1. Compilar correctamente con los flags:

    -Wall -Werror -std=c99 -pedantic
    
  2. validar la salida que se provee y que genere una copia de la entrda en la salida.

La entrega se realiza a través del sistema de entregas.

El ejercicio es de entrega individual.