diff --git a/du6/list_ops.c b/du6/list_ops.c index 6b48538..1df58f3 100644 --- a/du6/list_ops.c +++ b/du6/list_ops.c @@ -1,53 +1,51 @@ -#include "list_ops.h" #include +#include -// Funkcia na vytvorenie noveho zoznamu -list_t *new_list(size_t length, list_element_t elements[]) { - list_t *list = malloc(sizeof(list_t) + sizeof(list_element_t) * length); +typedef int list_element_t; + +typedef struct { + size_t length; + list_element_t elements[]; // flexibilné pole +} list_t; + +// Vytvorí nový zoznam s danou dĺžkou a prvkami nastavenými na default_value +list_t *new_list(size_t length, list_element_t default_value) { + list_t *list = malloc(sizeof(list_t) + length * sizeof(list_element_t)); if (list == NULL) { return NULL; } list->length = length; - - // Skopírujeme prvky zo vstupného poľa for (size_t i = 0; i < length; i++) { - list->elements[i] = elements[i]; + list->elements[i] = default_value; } return list; } -// Funkcia na spojenie dvoch zoznamov -list_t *append_list(list_t *list1, list_t *list2) { - size_t new_length = list1->length + list2->length; - - list_t *result = malloc(sizeof(list_t) + sizeof(list_element_t) * new_length); +// Pridá každý prvok zoznamu cez mapovaciu funkciu a vráti nový zoznam +list_t *map_list(list_t *list, list_element_t (*map_fn)(list_element_t)) { + list_t *result = malloc(sizeof(list_t) + sizeof(list_element_t) * list->length); if (result == NULL) { return NULL; } - result->length = new_length; + result->length = list->length; - // Skopírujeme prvky z prvého zoznamu - for (size_t i = 0; i < list1->length; i++) { - result->elements[i] = list1->elements[i]; - } - - // Potom skopírujeme prvky z druhého zoznamu - for (size_t i = 0; i < list2->length; i++) { - result->elements[list1->length + i] = list2->elements[i]; + for (size_t i = 0; i < list->length; i++) { + result->elements[i] = map_fn(list->elements[i]); } return result; } -// Funkcia na filtrovanie prvkov podľa podmienky -list_t *filter_list(list_t *list, bool (*filter)(list_element_t)) { - // Najprv zistíme, koľko prvkov bude vo výsledku +// Vytvorí nový zoznam s prvkami, ktoré spĺňajú filter podmienku +list_t *filter_list(list_t *list, bool (*filter_fn)(list_element_t)) { size_t count = 0; + + // Najprv zistíme koľko prvkov bude vo výsledku for (size_t i = 0; i < list->length; i++) { - if (filter(list->elements[i])) { + if (filter_fn(list->elements[i])) { count++; } } @@ -58,11 +56,10 @@ list_t *filter_list(list_t *list, bool (*filter)(list_element_t)) { } result->length = count; - - // Pridáme len tie prvky, ktoré prejdú filtrom size_t index = 0; + for (size_t i = 0; i < list->length; i++) { - if (filter(list->elements[i])) { + if (filter_fn(list->elements[i])) { result->elements[index] = list->elements[i]; index++; } @@ -71,56 +68,30 @@ list_t *filter_list(list_t *list, bool (*filter)(list_element_t)) { return result; } -// Vracia dĺžku zoznamu -size_t length_list(list_t *list) { - return list->length; -} - -// Funkcia na mapovanie - aplikuje funkciu na každý prvok -list_t *map_list(list_t *list, list_element_t (*map)(list_element_t)) { - list_t *result = malloc(sizeof(list_t) + sizeof(list_element_t) * list->length); - if (result == NULL) { - return NULL; - } - - result->length = list->length; +// Zredukuje zoznam zľava doprava pomocou fold funkcie +list_element_t foldl_list(list_t *list, list_element_t initial, list_element_t (*fold_fn)(list_element_t, list_element_t)) { + list_element_t acc = initial; for (size_t i = 0; i < list->length; i++) { - result->elements[i] = map(list->elements[i]); + acc = fold_fn(acc, list->elements[i]); } - return result; + return acc; } -// Funkcia foldl - zľava doprava -list_element_t foldl_list(list_t *list, list_element_t initial, - list_element_t (*foldl)(list_element_t, list_element_t)) { - list_element_t result = initial; +// Zredukuje zoznam sprava doľava pomocou fold funkcie +list_element_t foldr_list(list_t *list, list_element_t initial, list_element_t (*fold_fn)(list_element_t, list_element_t)) { + list_element_t acc = initial; - for (size_t i = 0; i < list->length; i++) { - result = foldl(result, list->elements[i]); + // Pozor: size_t je unsigned, preto treba použiť podmienku inak + for (size_t i = list->length; i > 0; i--) { + acc = fold_fn(list->elements[i - 1], acc); } - return result; + return acc; } -// Funkcia foldr - sprava doľava -list_element_t foldr_list(list_t *list, list_element_t initial, - list_element_t (*foldr)(list_element_t, list_element_t)) { - list_element_t result = initial; - - // Používame int namiesto size_t, aby sme vedeli ísť dozadu - int i = (int)list->length - 1; - - while (i >= 0) { - result = foldr(list->elements[i], result); - i--; - } - - return result; -} - -// Funkcia na otočenie zoznamu +// Otočí poradie prvkov v zozname list_t *reverse_list(list_t *list) { list_t *result = malloc(sizeof(list_t) + sizeof(list_element_t) * list->length); if (result == NULL) { @@ -129,7 +100,6 @@ list_t *reverse_list(list_t *list) { result->length = list->length; - // Prekopírujeme prvky v opačnom poradí for (size_t i = 0; i < list->length; i++) { result->elements[i] = list->elements[list->length - 1 - i]; } @@ -137,9 +107,7 @@ list_t *reverse_list(list_t *list) { return result; } -// Uvoľníme pamäť zoznamu +// Uvoľní pamäť alokovanú pre zoznam void delete_list(list_t *list) { free(list); } - -}