Commit 53ef42a1 authored by Acheto's avatar Acheto
Browse files

recu1

parent 3ad2df63
{
"configurations": [
{
"name": "linux-gcc-x64",
"includePath": [
"${workspaceFolder}/**"
],
"compilerPath": "/usr/bin/gcc",
"cStandard": "${default}",
"cppStandard": "${default}",
"intelliSenseMode": "linux-gcc-x64",
"compilerArgs": [
""
]
}
],
"version": 4
}
\ No newline at end of file
{
"version": "0.2.0",
"configurations": [
{
"name": "C/C++ Runner: Debug Session",
"type": "cppdbg",
"request": "launch",
"args": [],
"stopAtEntry": false,
"externalConsole": false,
"cwd": "/home/clinux01/Descargas/parcial-bundle.v0.1/entregable/parcial-bundle.v0.1/solucion/ej1",
"program": "/home/clinux01/Descargas/parcial-bundle.v0.1/entregable/parcial-bundle.v0.1/solucion/ej1/build/Debug/outDebug",
"MIMode": "gdb",
"miDebuggerPath": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
\ No newline at end of file
{
"C_Cpp_Runner.cCompilerPath": "gcc",
"C_Cpp_Runner.cppCompilerPath": "g++",
"C_Cpp_Runner.debuggerPath": "gdb",
"C_Cpp_Runner.cStandard": "",
"C_Cpp_Runner.cppStandard": "",
"C_Cpp_Runner.msvcBatchPath": "",
"C_Cpp_Runner.useMsvc": false,
"C_Cpp_Runner.warnings": [
"-Wall",
"-Wextra",
"-Wpedantic",
"-Wshadow",
"-Wformat=2",
"-Wconversion",
"-Wnull-dereference"
],
"C_Cpp_Runner.enableWarnings": true,
"C_Cpp_Runner.warningsAsError": false,
"C_Cpp_Runner.compilerArgs": [],
"C_Cpp_Runner.linkerArgs": [],
"C_Cpp_Runner.includePaths": [],
"C_Cpp_Runner.includeSearch": [
"*",
"**/*"
],
"C_Cpp_Runner.excludeSearch": [
"**/build",
"**/build/**",
"**/.*",
"**/.*/**",
"**/.vscode",
"**/.vscode/**"
]
}
\ No newline at end of file
CFLAGS += -Wall -Wextra -O0 -g -lm -Wno-unused-variable -Wno-unused-parameter -no-pie
all: tests_c tests_asm main_c main_asm
clean:
rm -f tests_c tests_asm main_c main_asm tests.o main.o lista_c.o lista_asm.o
run_tests: tests_asm
valgrind --show-reachable=yes --leak-check=full --error-exitcode=1 ./tests_asm \
&& echo "No se detectaron errores de memoria"
run_c_tests: tests_c
valgrind --show-reachable=yes --leak-check=full --error-exitcode=1 ./tests_c \
&& echo "No se detectaron errores de memoria"
tests_c: tests.o lista_c.o
$(CC) $(CFLAGS) $^ -o $@
tests_asm: tests.o lista_asm.o
$(CC) $(CFLAGS) $^ -o $@
main_c: main.o lista_c.o
$(CC) $(CFLAGS) $^ -o $@
main_asm: main.o lista_asm.o
$(CC) $(CFLAGS) $^ -o $@
lista_c.o: lista_c.c
lista_asm.o: lista_asm.asm
nasm -f elf64 -g $^ -o $@
.PHONY: all clean run_tests run_c_tests
next
tipo: lista_t*, tamaño: 8 bytes, offset: 0 bytes, alineación: 8 bytes
sum
tipo: uint32_t, tamaño: 4 bytes, offset: 4 bytes, alineación: 4 bytes
size:
tipo: uint64_t, tamaño: 8 bytes, offset: 0 bytes, alineación: 8 bytes
array:
tipo: uint64_t, tamaño: 8 bytes, offset: 0 bytes, alineación: 8 bytes
TOTAL:
tamaño: 32 bytes, alineación: 8 bytes
La estructura 'lista_t' tiene 0 bytes de padding (su último elemento tiene el mismo
tamaño que la alineación de la estructura).
#pragma once
#include <stdint.h>
#include <stddef.h>
typedef struct lista_s {
// Siguiente elemento de la lista o NULL si es el final
struct lista_s* next;
// Suma de los elementos en array
uint32_t sum;
// Cantidad de elementos en array
uint64_t size;
// El array en cuestión que posee este proyecto de la lista
uint32_t* array;
} lista_t;
uint32_t proyecto_mas_dificil(lista_t*);
void marcar_tarea_completada(lista_t*, size_t);
uint64_t* tareas_completadas_por_proyecto(lista_t*);
extern malloc
%define OFFSET_NEXT 0
%define OFFSET_SUM 8
%define OFFSET_SIZE 16
%define OFFSET_ARRAY 24
BITS 64
section .text
; uint32_t proyecto_mas_dificil(lista_t*)
;
; Dada una lista enlazada de proyectos devuelve el `sum` más grande de ésta.
;
; - El `sum` más grande de la lista vacía (`NULL`) es 0.
;
global proyecto_mas_dificil
proyecto_mas_dificil:
; COMPLETAR
push rbp
mov rbp, rsp
mov rsi, rdi ; rsi = listaTmp = lista
xor rax, rax ; eax = res
.loop:
cmp rsi, 0 ; if (lista == NULL) return res
je .fin
xor rdx, rdx
mov edx, [rsi + OFFSET_SUM] ; edx = lista->sum
mov rsi, [rsi + OFFSET_NEXT] ; lista = lista->next
cmp edx, eax ; if (sum <= res) continue
jle .loop
mov eax, edx
jmp .loop
.fin:
pop rbp
ret
; void tarea_completada(lista_t*, size_t)
;
; Dada una lista enlazada de proyectos y un índice en ésta setea la i-ésima
; tarea en cero.
;
; - La implementación debe "saltearse" a los proyectos sin tareas
; - Se puede asumir que el índice siempre es válido
; - Se debe actualizar el `sum` del nodo actualizado de la lista
;
global marcar_tarea_completada
marcar_tarea_completada:
push rbp
mov rbp, rsp
xor rcx, rcx ; rcx = curr_i
.loop:
cmp rdi, 0 ; if (lista == NULL)
je .endLoop
mov rdx, [rdi + OFFSET_SIZE] ; rdx = lista->size
add rdx, rcx ; rdx = lista->size + curr_i
cmp rdx, rsi ; if (curr_i + lista->size > index)
jg .endLoop
add rcx, [rdi + OFFSET_SIZE] ; curr_i += lista->size
mov rdi, [rdi + OFFSET_NEXT] ; lista = lista->next
.endLoop:
cmp rdi, 0 ; if (lista == NULL) return
je .prologo
sub rsi, rcx ; index -= curr_i
shl rsi, 2 ; index * sizeof(uint32_t)
mov r8, [rdi + OFFSET_ARRAY] ; r8 = &lista->array
add r8, rsi ; r8 = &lista->array[index]
lea r9, [rdi + OFFSET_SUM] ; r9 = &lista->sum
xor r10, r10
mov r10d, [r9]
sub r10d, [r8]
mov DWORD[r9], r10d ; lista->sum -= lista->array[index]
mov DWORD[r8], 0 ; lista->array[index] = 0
.prologo:
pop rbp
ret
; uint64_t* tareas_completadas_por_proyecto(lista_t*)
;
; Dada una lista enlazada de proyectos se devuelve un array que cuenta
; cuántas tareas completadas tiene cada uno de ellos.
;
; - Si se provee a la lista vacía como parámetro (`NULL`) la respuesta puede
; ser `NULL` o el resultado de `malloc(0)`
; - Los proyectos sin tareas tienen cero tareas completadas
; - Los proyectos sin tareas deben aparecer en el array resultante
; - Se provee una implementación esqueleto en C si se desea seguir el
; esquema implementativo recomendado
;
global tareas_completadas_por_proyecto
tareas_completadas_por_proyecto:
push rbp
mov rbp, rsp
push r12
push r13
push r14
push r15
mov r12, rdi ; r12 = lista
call lista_len ; rax = length = lista_len(lista)
mov r13, rax ; r13 = length
shl r13, 3 ; r13 = length * 8
mov rdi, r13 ; rdi = length * 8
shr r13, 3 ; r13 = length
call malloc ; rax = results = malloc(length * 8)
mov r14, rax ; r14 = results
xor r8, r8 ; i = 0
.loop:
cmp r8, r13
je .fin
mov rdi, [r12 + OFFSET_ARRAY] ; rdi = &lista->array
mov r15, [r12 + OFFSET_SIZE] ; r11 = &lista->size
mov rsi, r15 ; rsi = lista->size
call tareas_completadas
shl r8, 3 ; r8 = i * sizeof(uint64_t)
lea r9, [r14 + r8] ; r9 = &results[i]
shr r8, 3 ; r8 = i
mov QWORD[r9], rax ; results[i] = tareas_completadas(lista->array, lista->size)
mov r12, [r12] ; lista = lista->next
inc r8 ; i++
jmp .loop
.fin:
mov rax, r14
pop r15
pop r14
pop r13
pop r12
pop rbp
ret
; uint64_t lista_len(lista_t* lista)
;
; Dada una lista enlazada devuelve su longitud.
;
; - La longitud de `NULL` es 0
;
lista_len:
push rbp
mov rbp, rsp
xor rax, rax ; res = 0
.loop:
cmp rdi, 0 ; if (lista == NULL return res)
je .fin
inc rax ; res++
mov rdi, [rdi] ; lista = lista->next
jmp .loop
.fin:
pop rbp
ret
; uint64_t tareas_completadas(uint32_t* array, size_t size) {
;
; Dado un array de `size` enteros de 32 bits sin signo devuelve la cantidad de
; ceros en ese array.
;
; - Un array de tamaño 0 tiene 0 ceros.
tareas_completadas:
push rbp
mov rbp, rsp
xor rax, rax ; res = 0
xor rcx, rcx ; i = 0
.loop:
cmp rcx, rsi ; if (i == size return res)
je .fin
cmp DWORD[rdi + rcx*4], 0 ; if (array[i] == 0)
je .sumarEnRes
.siguienteElemento:
inc rcx ; i++
jmp .loop
.sumarEnRes:
inc rax ; res++
jmp .siguienteElemento
.fin:
pop rbp
ret
#include <stdlib.h>
#include "lista.h"
/**
* Dada una lista enlazada de proyectos devuelve el `sum` más grande de ésta.
*
* - El `sum` más grande de la lista vacía (`NULL`) es 0.
*/
uint32_t proyecto_mas_dificil(lista_t* lista) {
/* COMPLETAR */
uint32_t res = 0;
lista_t* listaTmp = lista;
while (lista != NULL)
{
uint32_t sum = lista->sum;
if (sum > res)
{
res = sum;
}
lista = lista->next;
}
lista = listaTmp;
return res;
}
/**
* Dada una lista enlazada de proyectos y un índice en ésta setea la i-ésima
* tarea en cero.
*
* - La implementación debe "saltearse" a los proyectos sin tareas
* - Se puede asumir que el índice siempre es válido
* - Se debe actualizar el `sum` del nodo actualizado de la lista
*/
void marcar_tarea_completada(lista_t* lista, size_t index) {
/* AYUDA: */
size_t curr_i = 0;
while (lista != NULL && curr_i + lista->size <= index) {
curr_i += lista->size;
lista = lista->next;
}
if (lista == NULL) {
return;
}
index -= curr_i;
lista->sum -= lista->array[index];
lista->array[index] = 0;
}
/**
* Dada una lista enlazada devuelve su longitud.
*
* - La longitud de `NULL` es 0
*/
uint64_t lista_len(lista_t* lista) {
uint64_t res = 0;
while (lista != NULL)
{
res++;
lista = lista->next;
}
return res;
}
/**
* Dado un array de `size` enteros de 32 bits sin signo devuelve la cantidad de
* ceros en ese array.
*
* - Un array de tamaño 0 tiene 0 ceros.
*/
uint64_t tareas_completadas(uint32_t* array, size_t size) {
uint64_t res = 0;
for (int i = 0; i < (int)size; i++)
{
if (array[i] == 0)
{
res++;
}
}
return res;
}
/**
* Dada una lista enlazada de proyectos se devuelve un array que cuenta
* cuántas tareas completadas tiene cada uno de ellos.
*
* - Si se provee a la lista vacía como parámetro (`NULL`) la respuesta puede
* ser `NULL` o el resultado de `malloc(0)`
* - Los proyectos sin tareas tienen cero tareas completadas
* - Los proyectos sin tareas deben aparecer en el array resultante
* - Se provee una implementación esqueleto en C si se desea seguir el
* esquema implementativo recomendado
*/
uint64_t* tareas_completadas_por_proyecto(lista_t* lista) {
size_t length = lista_len(lista);
uint64_t* results = malloc(length * sizeof(uint64_t));
for (size_t i = 0; i < length; i++) {
results[i] = tareas_completadas(lista->array, lista->size);
lista = lista->next;
}
return results;
}
#include "utils.h"
int main(int argc, char* argv[]) {
// Este es el lugar para hacer pruebas mientras se realiza el ejercicio
// A modo de ayuda se ofrece la macros PROYECTO para construir cada
// nodo de la lista fácilmente.
lista_t* mi_proyecto = PROYECTO(1, 2, 3, 4);
lista_t* una_tarea_muy_dificil = PROYECTO(99);
lista_t* vacio = PROYECTO();
// Además se tiene la función `imprimir_proyecto` para imprimir un
// proyecto dado.
puts("= Proyecto sencillo");
imprimir_proyecto(mi_proyecto);
puts("= Proyecto con una sola tarea");
imprimir_proyecto(una_tarea_muy_dificil);
puts("= Proyecto vacio");
imprimir_proyecto(vacio);
// A la hora de construir la lista se tiene también la macro LISTA que
// funciona de una forma similar.
lista_t* lista_vacia = LISTA(); // Es lo mismo que NULL
lista_t* lista_sencilla = LISTA(
PROYECTO(1, 2, 3, 4),
PROYECTO(9999),
PROYECTO()
);
lista_t* muchos_proyectos_vacios = LISTA(
PROYECTO(),
PROYECTO(),
PROYECTO()
);
// Y de igual manera se tiene a la funcion imprimir_proyectos para
// imprimir una lista de proyectos dada.
puts("= Lista de proyectos vacia");
imprimir_proyectos(lista_vacia);
puts("= Lista de proyectos sencilla");
imprimir_proyectos(lista_sencilla);
puts("= Lista de proyectos con proyectos vacios");
imprimir_proyectos(muchos_proyectos_vacios);
// Las macros LISTA y PROYECTO utilizan la pila, por lo que no deben
// preocuparse por liberar la memoria.
// Finalmente, se pueden usar para armar los parámetros in-situ.
puts("= Proyecto de prueba");
imprimir_proyecto(PROYECTO(100, 101, 102));
puts("= Lista de proyectos de ejemplo");
imprimir_proyectos(LISTA(
PROYECTO(10, 9, 8),
PROYECTO(1000),
PROYECTO(999)
));
//printf("%d", proyecto_mas_dificil(lista_sencilla));
//marcar_tarea_completada(lista_sencilla, 2);
//printf("%d, %d, %d, %d", lista_sencilla->array[0], lista_sencilla->array[1], lista_sencilla->array[2], lista_sencilla->array[3]);
//printf("%d", lista_sencilla->sum);
//printf("%d, %d, %d", tareas_completadas_por_proyecto(lista_sencilla)[0], tareas_completadas_por_proyecto(lista_sencilla)[1], tareas_completadas_por_proyecto(lista_sencilla)[2]);
return 0;
}
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
static size_t test__count = 0;
static size_t test__succeed__count = 0;
#define TEST(name) \
void name##__impl(const char* test__name, bool* test__fallo); \
void name() { \
test__count++; \
const char* test__name = #name; \
bool test__fallo = false; \
printf("- %s", test__name); \
name##__impl(test__name, &test__fallo); \
if (!test__fallo) { \
test__succeed__count++; \
printf(" OK\n"); \
} \
} \
void name##__impl(const char* test__name, bool* test__fallo)
#define TEST_ASSERT(cond) \
if (!(cond)) { \
printf(" FAILED\n"); \
printf(" fallo en %s:%d\n", __FILE__, __LINE__); \
printf(" %s\n", #cond); \
*test__fallo = true; \
return; \
}
static inline void tests_end() {
printf(
"Pasaron %ld de %ld tests\n",
test__succeed__count,
test__count
);
if (test__count == test__succeed__count) {
printf("¡Pasaron todos los tests!\n");
exit(0);
} else {
printf("Fallaron algunos tests.\n");
exit(1);
}
}
#include <stdbool.h>
#include <stdlib.h>
#include "utils.h"
#include "test-utils.h"
TEST(proyecto_mas_dificil_de_lista_vacia_cuesta_0) {
TEST_ASSERT(proyecto_mas_dificil(LISTA()) == 0);
}
TEST(proyecto_mas_dificil_si_no_hay_tareas_es_0) {
TEST_ASSERT(proyecto_mas_dificil(LISTA()) == 0);
TEST_ASSERT(proyecto_mas_dificil(LISTA(PROYECTO())) == 0);
TEST_ASSERT(proyecto_mas_dificil(LISTA(PROYECTO(), PROYECTO())) == 0);
TEST_ASSERT(proyecto_mas_dificil(LISTA(PROYECTO(), PROYECTO(), PROYECTO())) == 0);
}
TEST(proyecto_mas_dificil_con_una_sola_tarea_es_esa) {
TEST_ASSERT(proyecto_mas_dificil(LISTA(PROYECTO(99))) == 99);
TEST_ASSERT(proyecto_mas_dificil(LISTA(PROYECTO(), PROYECTO(123))) == 123);
TEST_ASSERT(proyecto_mas_dificil(LISTA(PROYECTO(1), PROYECTO(), PROYECTO())) == 1);
TEST_ASSERT(proyecto_mas_dificil(LISTA(PROYECTO(), PROYECTO(2), PROYECTO())) == 2);
TEST_ASSERT(proyecto_mas_dificil(LISTA(PROYECTO(), PROYECTO(), PROYECTO(3))) == 3);
}
TEST(proyecto_mas_dificil_usa_la_suma) {
TEST_ASSERT(proyecto_mas_dificil(LISTA(PROYECTO(1, 2, 3))) == 6);
TEST_ASSERT(proyecto_mas_dificil(LISTA(PROYECTO(100, 200, 10))) == 310);
}
TEST(proyecto_mas_dificil_calcula_el_maximo) {
TEST_ASSERT(proyecto_mas_dificil(LISTA(PROYECTO(1, 2, 3))) == 6);
TEST_ASSERT(proyecto_mas_dificil(LISTA(PROYECTO(3, 2, 1))) == 6);
TEST_ASSERT(proyecto_mas_dificil(LISTA(PROYECTO(1), PROYECTO(2), PROYECTO(3))) == 3);
TEST_ASSERT(proyecto_mas_dificil(LISTA(PROYECTO(3), PROYECTO(2), PROYECTO(1))) == 3);
TEST_ASSERT(proyecto_mas_dificil(LISTA(PROYECTO(10, 11, 12), PROYECTO(100, 90, 80))) == 270);
}
TEST(proyecto_mas_dificil_ignora_vacios) {
TEST_ASSERT(proyecto_mas_dificil(LISTA(
PROYECTO(),
PROYECTO(10, 11, 12),
PROYECTO(),
PROYECTO(20, 30, 40),
PROYECTO()
)) == 90);
}
TEST(proyecto_mas_dificil_ejemplos_del_enunciado) {
TEST_ASSERT(proyecto_mas_dificil(LISTA(
PROYECTO(1, 2, 3),
PROYECTO(98, 99),
PROYECTO(9)
)) == 197);
TEST_ASSERT(proyecto_mas_dificil(LISTA(
PROYECTO(),
PROYECTO(),
PROYECTO()
)) == 0);
TEST_ASSERT(proyecto_mas_dificil(LISTA(
PROYECTO(3),
PROYECTO(2, 1),
PROYECTO(1, 1, 1)
)) == 3);
TEST_ASSERT(proyecto_mas_dificil(LISTA(
PROYECTO(),
PROYECTO(1, 1, 1),
PROYECTO(100)
)) == 100);
TEST_ASSERT(proyecto_mas_dificil(NULL) == 0);
}
bool son_listas_iguales(lista_t* a, lista_t* b) {
if (a == NULL && b == NULL) {
return true;
}
if (a == NULL || b == NULL) {
return false;
}
if (a->sum != b->sum) {
return false;
}
if (a->size != b->size) {
return false;
}
for (size_t i = 0; i < a->size; i++) {
if (a->array[i] != b->array[i]) {
return false;
}
}
return son_listas_iguales(a->next, b->next);
}
TEST(marcar_tarea_completada_) {
}
TEST(marcar_tarea_completada_accede_al_primero_como_array) {
lista_t* lista = LISTA(PROYECTO(99, 98, 97));
marcar_tarea_completada(lista, 0);
TEST_ASSERT(lista->array[0] == 0);
marcar_tarea_completada(lista, 1);
TEST_ASSERT(lista->array[1] == 0);
marcar_tarea_completada(lista, 2);
TEST_ASSERT(lista->array[2] == 0);
}
TEST(marcar_tarea_completada_puede_atravesar_la_lista) {
lista_t* lista = LISTA(
PROYECTO(1, 2, 3),
PROYECTO(10, 20, 30),
PROYECTO(100, 200, 300)
);
marcar_tarea_completada(lista, 1);
TEST_ASSERT(lista->array[1] == 0);
marcar_tarea_completada(lista, 3);
TEST_ASSERT(lista->next->array[0] == 0);
marcar_tarea_completada(lista, 8);
TEST_ASSERT(lista->next->next->array[2] == 0);
}
TEST(marcar_tarea_completada_actualiza_la_suma) {
lista_t* lista = LISTA(PROYECTO(1, 2, 3));
TEST_ASSERT(lista->sum == 6)
marcar_tarea_completada(lista, 0);
TEST_ASSERT(lista->sum == 5)
marcar_tarea_completada(lista, 1);
TEST_ASSERT(lista->sum == 3)
marcar_tarea_completada(lista, 2);
TEST_ASSERT(lista->sum == 0)
}
TEST(marcar_tarea_completada_ignora_proyectos_vacios) {
lista_t* vacios_en_el_medio = LISTA(PROYECTO(1), PROYECTO(), PROYECTO(), PROYECTO(2));
marcar_tarea_completada(vacios_en_el_medio, 1);
TEST_ASSERT(son_listas_iguales(
vacios_en_el_medio,
LISTA(PROYECTO(1), PROYECTO(), PROYECTO(), PROYECTO(0))
));
lista_t* vacios_al_principio = LISTA(PROYECTO(), PROYECTO(), PROYECTO(1), PROYECTO(2));
marcar_tarea_completada(vacios_al_principio, 0);
TEST_ASSERT(son_listas_iguales(
vacios_al_principio,
LISTA(PROYECTO(), PROYECTO(), PROYECTO(0), PROYECTO(2))
));
marcar_tarea_completada(vacios_al_principio, 1);
TEST_ASSERT(son_listas_iguales(
vacios_al_principio,
LISTA(PROYECTO(), PROYECTO(), PROYECTO(0), PROYECTO(0))
));
}
TEST(marcar_tarea_completada_ejemplos_del_enunciado) {
lista_t* ejemplo1 = LISTA(PROYECTO(1, 2, 3));
marcar_tarea_completada(ejemplo1, 0);
TEST_ASSERT(son_listas_iguales(
ejemplo1,
LISTA(PROYECTO(0, 2, 3))
));
lista_t* ejemplo2 = LISTA(PROYECTO(), PROYECTO(1));
marcar_tarea_completada(ejemplo2, 0);
TEST_ASSERT(son_listas_iguales(
ejemplo2,
LISTA(PROYECTO(), PROYECTO(0))
));
lista_t* ejemplo3 = LISTA(PROYECTO(1, 2, 3), PROYECTO(4, 5));
marcar_tarea_completada(ejemplo3, 4);
TEST_ASSERT(son_listas_iguales(
ejemplo3,
LISTA(PROYECTO(1, 2, 3), PROYECTO(4, 0))
));
lista_t* ejemplo4 = LISTA(PROYECTO(1), PROYECTO(2), PROYECTO(3));
marcar_tarea_completada(ejemplo4, 2);
TEST_ASSERT(son_listas_iguales(
ejemplo4,
LISTA(PROYECTO(1), PROYECTO(2), PROYECTO(0))
));
lista_t* ejemplo5 = LISTA(PROYECTO(1), PROYECTO(2), PROYECTO(3));
marcar_tarea_completada(ejemplo5, 1);
TEST_ASSERT(son_listas_iguales(
ejemplo5,
LISTA(PROYECTO(1), PROYECTO(0), PROYECTO(3))
));
}
bool son_arrays_iguales(size_t size, uint64_t a[], uint64_t b[]) {
for (size_t i = 0; i < size; i++) {
if (a[i] != b[i]) {
return false;
}
}
return true;
}
TEST(tareas_completadas_por_proyecto_proyecto_vacio_da_cero) {
uint64_t* un_proyecto_vacio =
tareas_completadas_por_proyecto(LISTA(PROYECTO()));
TEST_ASSERT(son_arrays_iguales(
1, /* Elementos en el array */
un_proyecto_vacio,
(uint64_t[]) { 0 }
))
free(un_proyecto_vacio);
uint64_t* dos_proyectos_vacios =
tareas_completadas_por_proyecto(LISTA(PROYECTO(), PROYECTO()));
TEST_ASSERT(son_arrays_iguales(
2, /* Elementos en el array */
dos_proyectos_vacios,
(uint64_t[]) { 0, 0 }
))
free(dos_proyectos_vacios);
uint64_t* tres_proyectos_vacios =
tareas_completadas_por_proyecto(LISTA(PROYECTO(), PROYECTO(), PROYECTO()));
TEST_ASSERT(son_arrays_iguales(
3, /* Elementos en el array */
tres_proyectos_vacios,
(uint64_t[]) { 0, 0, 0 }
))
free(tres_proyectos_vacios);
}
TEST(tareas_completadas_por_proyecto_cuenta_ceros_si_son_todos_ceros) {
uint64_t* un_proyecto_con_dos_ceros =
tareas_completadas_por_proyecto(LISTA(PROYECTO(0, 0)));
TEST_ASSERT(son_arrays_iguales(
1, /* Elementos en el array */
un_proyecto_con_dos_ceros,
(uint64_t[]) { 2 }
))
free(un_proyecto_con_dos_ceros);
uint64_t* un_cero_y_nueve_ceros =
tareas_completadas_por_proyecto(LISTA(
PROYECTO(0),
PROYECTO(0, 0, 0, 0, 0, 0, 0, 0, 0)
));
TEST_ASSERT(son_arrays_iguales(
2, /* Elementos en el array */
un_cero_y_nueve_ceros,
(uint64_t[]) { 1, 9 }
))
free(un_cero_y_nueve_ceros);
uint64_t* uno_dos_y_tres_ceros =
tareas_completadas_por_proyecto(LISTA(
PROYECTO(0),
PROYECTO(0, 0),
PROYECTO(0, 0, 0)
));
TEST_ASSERT(son_arrays_iguales(
3, /* Elementos en el array */
uno_dos_y_tres_ceros,
(uint64_t[]) { 1, 2, 3 }
))
free(uno_dos_y_tres_ceros);
}
TEST(tareas_completadas_por_proyecto_no_cuenta_no_ceros) {
uint64_t* uno_dos_tres =
tareas_completadas_por_proyecto(LISTA(
PROYECTO(1, 2, 3)
));
TEST_ASSERT(son_arrays_iguales(
1, /* Elementos en el array */
uno_dos_tres,
(uint64_t[]) { 0 }
))
free(uno_dos_tres);
uint64_t* uno_dos_y_tres =
tareas_completadas_por_proyecto(LISTA(
PROYECTO(1, 2), PROYECTO(3)
));
TEST_ASSERT(son_arrays_iguales(
1, /* Elementos en el array */
uno_dos_y_tres,
(uint64_t[]) { 0, 0 }
))
free(uno_dos_y_tres);
uint64_t* uno_y_dos_y_tres =
tareas_completadas_por_proyecto(LISTA(
PROYECTO(1), PROYECTO(2), PROYECTO(3)
));
TEST_ASSERT(son_arrays_iguales(
1, /* Elementos en el array */
uno_y_dos_y_tres,
(uint64_t[]) { 0, 0, 0 }
))
free(uno_y_dos_y_tres);
}
TEST(tareas_completadas_por_proyecto_ejemplos_del_enunciado) {
// NOTA: El test de ejemplo1 realmente no está testeando mucho.
uint64_t* ejemplo1 = tareas_completadas_por_proyecto(NULL);
TEST_ASSERT(son_arrays_iguales(0, ejemplo1, (uint64_t[]){}))
free(ejemplo1);
uint64_t* ejemplo2 = tareas_completadas_por_proyecto(LISTA(PROYECTO()));
TEST_ASSERT(son_arrays_iguales(1, ejemplo2, (uint64_t[]){ 0 }))
free(ejemplo2);
uint64_t* ejemplo3 = tareas_completadas_por_proyecto(LISTA(PROYECTO(), PROYECTO()));
TEST_ASSERT(son_arrays_iguales(2, ejemplo3, (uint64_t[]){ 0, 0 }))
free(ejemplo3);
uint64_t* ejemplo4 = tareas_completadas_por_proyecto(LISTA(PROYECTO(1, 2, 3)));
TEST_ASSERT(son_arrays_iguales(1, ejemplo4, (uint64_t[]){ 0 }))
free(ejemplo4);
uint64_t* ejemplo5 = tareas_completadas_por_proyecto(LISTA(PROYECTO(0, 2, 0)));
TEST_ASSERT(son_arrays_iguales(1, ejemplo5, (uint64_t[]){ 2 }))
free(ejemplo5);
uint64_t* ejemplo6 = tareas_completadas_por_proyecto(LISTA(PROYECTO(1, 2), PROYECTO(3, 4)));
TEST_ASSERT(son_arrays_iguales(2, ejemplo6, (uint64_t[]){ 0, 0 }))
free(ejemplo6);
uint64_t* ejemplo7 = tareas_completadas_por_proyecto(LISTA(PROYECTO(1, 2), PROYECTO(0, 0)));
TEST_ASSERT(son_arrays_iguales(2, ejemplo7, (uint64_t[]){ 0, 2 }))
free(ejemplo7);
uint64_t* ejemplo8 = tareas_completadas_por_proyecto(LISTA(PROYECTO(1, 0), PROYECTO(0, 4)));
TEST_ASSERT(son_arrays_iguales(2, ejemplo8, (uint64_t[]){ 1, 1 }))
free(ejemplo8);
}
int main(void) {
printf("= Tests de proyecto_mas_dificil(lista_t*)\n");
printf("=========================================\n");
proyecto_mas_dificil_de_lista_vacia_cuesta_0();
proyecto_mas_dificil_si_no_hay_tareas_es_0();
proyecto_mas_dificil_con_una_sola_tarea_es_esa();
proyecto_mas_dificil_usa_la_suma();
proyecto_mas_dificil_calcula_el_maximo();
proyecto_mas_dificil_ignora_vacios();
proyecto_mas_dificil_ejemplos_del_enunciado();
printf("\n");
printf("= Tests de marcar_tarea_completada(lista_t*, size_t)\n");
printf("====================================================\n");
marcar_tarea_completada_accede_al_primero_como_array();
marcar_tarea_completada_puede_atravesar_la_lista();
marcar_tarea_completada_actualiza_la_suma();
marcar_tarea_completada_ignora_proyectos_vacios();
marcar_tarea_completada_ejemplos_del_enunciado();
printf("\n");
printf("= Tests de tareas_completadas_por_proyecto(lista_t*, size_t)\n");
printf("============================================================\n");
tareas_completadas_por_proyecto_proyecto_vacio_da_cero();
tareas_completadas_por_proyecto_cuenta_ceros_si_son_todos_ceros();
tareas_completadas_por_proyecto_no_cuenta_no_ceros();
tareas_completadas_por_proyecto_ejemplos_del_enunciado();
printf("\n");
tests_end();
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment