Initialization

This commit is contained in:
Kozar 2024-03-14 16:10:50 +01:00
parent 98369fd5cf
commit 9927d7645b
7 changed files with 55 additions and 347 deletions

View File

@ -1,19 +0,0 @@
# Instructions
Implement basic list operations.
In functional languages list operations like `length`, `map`, and `reduce` are very common.
Implement a series of basic list operations, without using existing functions.
The precise number and names of the operations to be implemented will be track dependent to avoid conflicts with existing names, but the general operations you will implement include:
- `append` (*given two lists, add all items in the second list to the end of the first list*);
- `concatenate` (*given a series of lists, combine all items in all lists into one flattened list*);
- `filter` (*given a predicate and a list, return the list of all items for which `predicate(item)` is True*);
- `length` (*given a list, return the total number of items within it*);
- `map` (*given a function and a list, return the list of the results of applying `function(item)` on all items*);
- `foldl` (*given a function, a list, and initial accumulator, fold (reduce) each item into the accumulator from the left*);
- `foldr` (*given a function, a list, and an initial accumulator, fold (reduce) each item into the accumulator from the right*);
- `reverse` (*given a list, return a list with all the original items, but in reversed order*).
Note, the ordering in which arguments are passed to the fold functions (`foldl`, `foldr`) is significant.

View File

@ -1,25 +0,0 @@
{
"authors": [
"wolf99"
],
"contributors": [
"patricksjackson",
"rootbeersoup",
"ryanplusplus",
"xihh87"
],
"files": {
"solution": [
"list_ops.c",
"list_ops.h"
],
"test": [
"test_list_ops.c"
],
"example": [
".meta/example.c",
".meta/example.h"
]
},
"blurb": "Implement basic list operations."
}

View File

@ -1,134 +0,0 @@
#include "list_ops.h"
#include <string.h>
list_t *new_list(size_t length, list_element_t elements[])
{
list_t *list = malloc(sizeof(*list) + sizeof(list_element_t) * length);
if (!list)
return NULL;
list->length = length;
memcpy(list->elements, elements, sizeof(list_element_t) * length);
return list;
}
list_t *append_list(list_t *list1, list_t *list2)
{
if (!list1 || !list2)
return NULL;
size_t length = list1->length + list2->length;
list_t *list = malloc(sizeof(*list) + sizeof(list_element_t) * (length));
if (!list)
return NULL;
list->length = length;
if (length) {
memcpy(list->elements, list1->elements,
sizeof(list_element_t) * list1->length);
memcpy(&(list->elements[list1->length]), list2->elements,
sizeof(list_element_t) * list2->length);
}
return list;
}
list_t *filter_list(list_t *list, bool (*filter)(list_element_t))
{
if (!list || !filter)
return NULL;
list_t *filtered =
malloc(sizeof(*list) + sizeof(list_element_t) * list->length);
if (!filtered)
return NULL;
size_t j = 0;
for (size_t i = 0; i < list->length && j < list->length; ++i) {
if (filter(list->elements[i]))
filtered->elements[j++] = list->elements[i];
}
filtered->length = j;
return filtered;
}
size_t length_list(list_t *list)
{
if (!list)
return 0;
return list->length;
}
list_t *map_list(list_t *list, list_element_t (*map)(list_element_t))
{
if (!list || !map)
return NULL;
list_t *mapped =
malloc(sizeof(*list) + sizeof(list_element_t) * list->length);
if (!mapped)
return NULL;
mapped->length = list->length;
for (size_t i = 0; i < mapped->length; ++i)
mapped->elements[i] = map(list->elements[i]);
return mapped;
}
list_element_t foldl_list(list_t *list, list_element_t initial,
list_element_t (*foldl)(list_element_t,
list_element_t))
{
if (!list || !foldl)
return 0;
for (size_t i = 0; i < list->length; ++i)
initial = foldl(list->elements[i], initial);
return initial;
}
list_element_t foldr_list(list_t *list, list_element_t initial,
list_element_t (*foldr)(list_element_t,
list_element_t))
{
if (!list || !foldr)
return 0;
for (size_t i = list->length; i > 0; --i)
initial = foldr(list->elements[i - 1], initial);
return initial;
}
list_t *reverse_list(list_t *list)
{
if (!list)
return NULL;
list_t *reversed =
malloc(sizeof(*list) + sizeof(list_element_t) * list->length);
if (!reversed)
return NULL;
reversed->length = list->length;
for (size_t i = 0, j = reversed->length - 1; i < reversed->length;
i++, j--) {
reversed->elements[i] = list->elements[j];
}
return reversed;
}
void delete_list(list_t *list)
{
free(list);
}

View File

@ -1,47 +0,0 @@
#ifndef LIST_OPS_H
#define LIST_OPS_H
#include <stdlib.h>
#include <stdbool.h>
typedef int list_element_t;
typedef struct {
size_t length;
list_element_t elements[];
} list_t;
// constructs a new list
list_t *new_list(size_t length, list_element_t elements[]);
// append entries to a list and return the new list
list_t *append_list(list_t *list1, list_t *list2);
// filter list returning only values that satisfy the filter function
list_t *filter_list(list_t *list, bool (*filter)(list_element_t));
// returns the length of the list
size_t length_list(list_t *list);
// return a list of elements whose values equal the list value transformed by
// the mapping function
list_t *map_list(list_t *list, list_element_t (*map)(list_element_t));
// folds (reduces) the given list from the left with a function
list_element_t foldl_list(list_t *list, list_element_t initial,
list_element_t (*foldl)(list_element_t,
list_element_t));
// folds (reduces) the given list from the right with a function
list_element_t foldr_list(list_t *list, list_element_t initial,
list_element_t (*foldr)(list_element_t,
list_element_t));
// reverse the elements of the list
list_t *reverse_list(list_t *list);
// destroy the entire list
// list will be a dangling pointer after calling this method on it
void delete_list(list_t *list);
#endif

View File

@ -1,105 +0,0 @@
# This is an auto-generated file. Regular comments will be removed when this
# file is regenerated. Regenerating will not touch any manually added keys,
# so comments can be added in a "comment" key.
[485b9452-bf94-40f7-a3db-c3cf4850066a]
description = "empty lists"
[2c894696-b609-4569-b149-8672134d340a]
description = "list to empty list"
[e842efed-3bf6-4295-b371-4d67a4fdf19c]
description = "empty list to list"
[71dcf5eb-73ae-4a0e-b744-a52ee387922f]
description = "non-empty lists"
[28444355-201b-4af2-a2f6-5550227bde21]
description = "empty list"
include = false
[331451c1-9573-42a1-9869-2d06e3b389a9]
description = "list of lists"
include = false
comment = "C does not easily allow a single implementation for multiple types (Liskov substitution)"
[d6ecd72c-197f-40c3-89a4-aa1f45827e09]
description = "list of nested lists"
include = false
comment = "C does not easily allow a single implementation for multiple types (Liskov substitution)"
[0524fba8-3e0f-4531-ad2b-f7a43da86a16]
description = "empty list"
[88494bd5-f520-4edb-8631-88e415b62d24]
description = "non-empty list"
[1cf0b92d-8d96-41d5-9c21-7b3c37cb6aad]
description = "empty list"
[d7b8d2d9-2d16-44c4-9a19-6e5f237cb71e]
description = "non-empty list"
[c0bc8962-30e2-4bec-9ae4-668b8ecd75aa]
description = "empty list"
[11e71a95-e78b-4909-b8e4-60cdcaec0e91]
description = "non-empty list"
[613b20b7-1873-4070-a3a6-70ae5f50d7cc]
description = "empty list"
include = false
[e56df3eb-9405-416a-b13a-aabb4c3b5194]
description = "direction independent function applied to non-empty list"
include = false
coment = "reimplemented"
[d2cf5644-aee1-4dfc-9b88-06896676fe27]
description = "direction dependent function applied to non-empty list"
[36549237-f765-4a4c-bfd9-5d3a8f7b07d2]
description = "empty list"
[7a626a3c-03ec-42bc-9840-53f280e13067]
description = "direction independent function applied to non-empty list"
[d7fcad99-e88e-40e1-a539-4c519681f390]
description = "direction dependent function applied to non-empty list"
include = false
comment = "Prefer integer division test case (d2cf5644-aee1-4dfc-9b88-06896676fe27)"
[aeb576b9-118e-4a57-a451-db49fac20fdc]
description = "empty list"
include = false
coment = "reimplemented"
[c4b64e58-313e-4c47-9c68-7764964efb8e]
description = "direction independent function applied to non-empty list"
include = false
coment = "reimplemented"
[be396a53-c074-4db3-8dd6-f7ed003cce7c]
description = "direction dependent function applied to non-empty list"
[17214edb-20ba-42fc-bda8-000a5ab525b0]
description = "empty list"
[e1c64db7-9253-4a3d-a7c4-5273b9e2a1bd]
description = "direction independent function applied to non-empty list"
[8066003b-f2ff-437e-9103-66e6df474844]
description = "direction dependent function applied to non-empty list"
include = false
comment = "Prefer integer division test case (be396a53-c074-4db3-8dd6-f7ed003cce7c)"
[94231515-050e-4841-943d-d4488ab4ee30]
description = "empty list"
[fcc03d1e-42e0-4712-b689-d54ad761f360]
description = "non-empty list"
[40872990-b5b8-4cb8-9085-d91fc0d05d26]
description = "list of lists is not flattened"
include = false
comment = "C does not easily allow a single implementation for multiple types (Liskov substitution)"

Binary file not shown.

View File

@ -39,11 +39,30 @@ list_t *append_list(list_t *list1, list_t *list2) {
}
// filter list returning only values that satisfy the filter function
list_t *filter_list(list_t *list, bool (*filter)(list_element_t)){
return NULL;
list_t *filter_list(list_t *list, bool (*filter)(list_element_t)) {
if (list == NULL) return NULL;
size_t filteredLength = 0;
for (size_t i = 0; i < list->length; ++i) {
if (filter(list->elements[i])) {
++filteredLength;
}
}
list_t *filtered = malloc(sizeof(list_t) + filteredLength * sizeof(list_element_t));
if (filtered != NULL) {
filtered->length = filteredLength;
size_t j = 0;
for (size_t i = 0; i < list->length; ++i) {
if (filter(list->elements[i])) {
filtered->elements[j++] = list->elements[i];
}
}
}
return filtered;
}
// returns the length of the list
size_t length_list(list_t *list) {
return (list != NULL) ? list->length : 0;
@ -64,28 +83,47 @@ list_t *map_list(list_t *list, list_element_t (*map)(list_element_t)) {
}
// folds (reduces) the given list from the left with a function
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 accumulator = initial;
return res;
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 accumulator = initial;
if (list != NULL) {
for (size_t i = 0; i < list->length; ++i) {
accumulator = foldl(list->elements[i], accumulator);
}
}
return accumulator;
}
// folds (reduces) the given list from the right with a function
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 res=0;
return res;
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 accumulator = initial;
if (list != NULL) {
for (size_t i = list->length; i > 0; --i) {
accumulator = foldr(list->elements[i - 1], accumulator);
}
}
return accumulator;
}
// reverse the elements of the list
list_t *reverse_list(list_t *list){
return NULL;
list_t *reverse_list(list_t *list) {
if (list == NULL) return NULL;
list_t *reversedList = new_list(list->length, list->elements);
if (reversedList != NULL) {
for (size_t i = 0; i < list->length / 2; ++i) {
list_element_t temp = reversedList->elements[i];
reversedList->elements[i] = reversedList->elements[list->length - i - 1];
reversedList->elements[list->length - i - 1] = temp;
}
}
return reversedList;
}
// destroy the entire list
// list will be a dangling pointer after calling this method on it
void delete_list(list_t *list){
void delete_list(list_t *list) {
free(list);
}