Skip to content

Commit

Permalink
Listas: Nuevos foldeos (#129)
Browse files Browse the repository at this point in the history
* list: added new folds

* list: get maximum and minimum update

* list: fold1 update

* Update CHANGELOG.md
  • Loading branch information
RaniAgus authored Apr 7, 2021
1 parent a207964 commit 834e821
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 18 deletions.
9 changes: 6 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
#### Features

- La interfaz de `temporal_get_string_time()` cambió a `temporal_get_string_time(1)`,
recibiendp por parámetro el formato de fecha a devolver.
recibiendo por parámetro el formato de fecha a devolver.
- Se añadió un iterador externo para `t_list` con sus operaciones básicas
`create()`, `has_next()`, `next()`, `remove()` y `destroy()`.
- Se añadió un insertar ordenado para `t_list`: `list_add_sorted(3)`.
- Se añadieron nuevos foldeos para `t_list`: `list_fold1(2)`, `list_get_minimum(2)` y
`list_get_maximum(2)`.

#### Bugs

Expand All @@ -19,5 +21,6 @@ cuando estos eran el string vacío.
- Se corrigió un bug de `list_take()` y `list_take_and_remove()` que hacía que se
devolviera una lista inconsistente cuando el count recibido era mayor
al tamaño de la lista.
- Se corrigió el comportamiento de las funciones de t_list que recibían un index
y ocultaban el error en caso de que este no sea válido. Este comportamiento ya no pasa y el error queda expuesto
- Se corrigió el comportamiento de las funciones de `t_list` que recibían un index
y ocultaban el error en caso de que este no sea válido. Este comportamiento ya no
pasa y el error queda expuesto.
33 changes: 23 additions & 10 deletions src/commons/collections/list.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ static t_link_element* list_find_element(t_list *self, bool(*cutting_condition)(
static int list_add_element(t_list* self, t_link_element* element, bool(*cutting_condition)(t_link_element*, int));
static t_link_element* list_remove_element(t_list *self, bool(*cutting_condition)(t_link_element*, int));
static void list_append_to_sublist(t_list* sublist, t_list *self, bool(*condition)(void*, int), void* (*transformer)(void*));
static void* list_fold_elements(t_link_element* element, void* seed, void*(*operation)(void*, void*));

t_list *list_create() {
t_list *list = malloc(sizeof(t_list));
Expand Down Expand Up @@ -304,18 +305,20 @@ t_list* list_duplicate(t_list* self) {
return duplicated;
}

void* list_fold(t_list* self, void* seed, void*(*operation)(void*, void*))
{
t_link_element* element = self->head;
void* result = seed;
void* list_fold1(t_list* self, void* (*operation)(void*, void*)) {
return list_fold_elements(self->head->next, self->head->data, operation);
}

while(element != NULL)
{
result = operation(result, element->data);
element = element->next;
}
void* list_fold(t_list* self, void* seed, void*(*operation)(void*, void*)) {
return list_fold_elements(self->head, seed, operation);
}

return result;
void* list_get_minimum(t_list* self, void* (*minimum)(void*, void*)) {
return list_fold1(self, minimum);
}

void* list_get_maximum(t_list* self, void* (*maximum)(void*, void*)) {
return list_fold1(self, maximum);
}

t_list_iterator* list_iterator_create(t_list* list) {
Expand Down Expand Up @@ -449,3 +452,13 @@ static void list_append_to_sublist(t_list* sublist, t_list *self, bool(*conditio
aux = aux->next;
}
}

static void* list_fold_elements(t_link_element* element, void* seed, void*(*operation)(void*, void*)) {
void* result = seed;
while(element != NULL) {
result = operation(result, element->data);
element = element->next;
}

return result;
}
31 changes: 27 additions & 4 deletions src/commons/collections/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,20 @@
*/
void *list_get(t_list *, int index);

/**
* @NAME: list_get_minimum
* @DESC: Retorna el minimo de la lista según el comparador
* El comparador devuelve cuál es el mínimo de dos valores
*/
void *list_get_minimum(t_list* self, void* (*minimum)(void*, void*));

/**
* @NAME: list_get_maximum
* @DESC: Retorna el maximo de la lista según el comparador
* El comparador devuelve cuál es el máximo de dos valores
*/
void *list_get_maximum(t_list* self, void* (*maximum)(void*, void*));

/**
* @NAME: list_take
* @DESC: Retorna una nueva lista con
Expand Down Expand Up @@ -235,12 +249,21 @@
**/
t_list* list_duplicate(t_list* self);

/**
* @NAME: list_fold1
* @DESC: Devuelve un valor que resulta de aplicar la operacion entre todos los elementos
* de la lista, tomando al primero como semilla y partiendo desde el segundo (si existe).
*
* La funcion 'operation' debe recibir dos valores del tipo de los elementos de la lista.
*/
void* list_fold1(t_list* self, void* (*operation)(void*, void*));

/**
* @NAME: list_fold
* @DESC: Devuelve un valor que resulta de aplicar la
* operacion entre todos los elementos de la lista, partiendo desde el primero.
*
* La funcion 'operation' debe recibir 2 dos valores, uno del tipo del valor initial (seed)
* @DESC: Devuelve un valor que resulta de aplicar la operacion entre todos los elementos
* de la lista, partiendo desde el primero.
*
* La funcion 'operation' debe recibir dos valores: uno del tipo del valor initial (seed)
* y otro del tipo de los elementos de la lista.
*/
void* list_fold(t_list* self, void* seed, void*(*operation)(void*, void*));
Expand Down
44 changes: 43 additions & 1 deletion tests/unit-tests/test_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ static bool _ayudantes_alfabetico(t_person *primero, t_person *segundo) {
return strcmp(primero->name, segundo->name) <= 0;
}

static void* _ayudantes_minimo_edad(t_person* person1, t_person* person2) {
return person1->age <= person2->age ? person1 : person2;
}

static void* _ayudantes_maximo_edad(t_person* person1, t_person* person2) {
return person1->age >= person2->age ? person1 : person2;
}

context (test_list) {

void assert_person(t_person *person, char* name, int age) {
Expand Down Expand Up @@ -512,6 +520,40 @@ context (test_list) {

} end

describe("Fold1") {
before {
list_add(list, persona_create("Nicolas", 6));
list_add(list, persona_create("Matias", 70));
list_add(list, persona_create("Juan", 124));
list_add(list, persona_create("Juan Manuel", 1));
list_add(list, persona_create("Sebastian", 8));
list_add(list, persona_create("Rodrigo", 40));
} end

it("should fold all values into a single one, starting with first element") {
t_person* get_oldest_person(t_person* person1, t_person* person2) {
return person1->age >= person2->age ? person1 : person2;
}

t_person* oldestPerson = (t_person*) list_fold1(list, (void*) get_oldest_person);

assert_person(oldestPerson, "Juan", 124);
} end

it("should get minimum") {
t_person* youngestPerson = (t_person*) list_get_minimum(list, (void*)_ayudantes_minimo_edad);

assert_person(youngestPerson, "Juan Manuel", 1);
} end

it("should get maximum") {
t_person* oldestPerson = (t_person*) list_get_maximum(list, (void*)_ayudantes_maximo_edad);

assert_person(oldestPerson, "Juan", 124);
} end

} end

describe ("Fold") {

before {
Expand Down Expand Up @@ -545,7 +587,7 @@ context (test_list) {
return accum + person->age;
}

int sum = list_fold(list, 0, (void*) add_age);
int sum = (int)list_fold(list, 0, (void*) add_age);
should_int(sum) be equal to(273);
} end

Expand Down

0 comments on commit 834e821

Please sign in to comment.