From 85b81148f7cbc6ffefa6285062264c1b82cc71d6 Mon Sep 17 00:00:00 2001 From: Evan Burkey Date: Wed, 29 Nov 2023 14:39:59 -0800 Subject: [PATCH] add min/max to vectors --- docs/vector.md | 32 +++++++++++++++++++++++++++++++- include/lfvector.h | 8 ++++++++ src/vector.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ tests/tests.c | 7 +++++++ 4 files changed, 92 insertions(+), 1 deletion(-) diff --git a/docs/vector.md b/docs/vector.md index a37c3ab..34c22e2 100644 --- a/docs/vector.md +++ b/docs/vector.md @@ -117,11 +117,41 @@ Shrinks the capacity of the vector down to the current length. Returns a non-zer int vec_shrink(Vector *vec); ``` +## vec_max + +Finds the largest value in the vector and returns a void pointer to the underlying data. Requires a +comparison function to compare the data in the vector. This function must return `1` if `a > b`, `-1` if +`a < b`, or `0` if `a == b`. See the supplied comparison functions below for reference + +```c +const void *vec_min(const Vector *vec, int(*cmp)(const void *a, const void *b)); +``` + +## vec_min + +Finds the smallest value in the vector and returns a void pointer to the underlying data. Requires a +comparison function to compare the data in the vector. This function must return `1` if `a > b`, `-1` if +`a < b`, or `0` if `a == b`. See the supplied comparison functions below for reference + +```c +const void *vec_max(const Vector *vec, int(*cmp)(const void *a, const void *b)); +``` + +## Comparison Functions + +Comparison functions to compare data in a vector. These functions must return `1` if `a > b`, `-1` if +`a < b`, or `0` if `a == b`. + +```c +int vec_cmp_int(const void *a, const void *b); +int vec_cmp_char(const void *a, const void *b); +``` + ## Macros ### vec_at -Grabs the element at index `i` without safety checks for better performance. +Grabs the element at index `i` without safety checks for better performance. Use with caution ```c #define vec_at(v, i) (v)->elements[(i)] diff --git a/include/lfvector.h b/include/lfvector.h index d9e892f..c0c7a63 100644 --- a/include/lfvector.h +++ b/include/lfvector.h @@ -26,6 +26,14 @@ void *vec_remove(Vector *vec, size_t index); int vec_shrink(Vector *vec); +const void *vec_min(const Vector *vec, int(*cmp)(const void *a, const void *b)); + +const void *vec_max(const Vector *vec, int(*cmp)(const void *a, const void *b)); + +int vec_cmp_int(const void *a, const void *b); + +int vec_cmp_char(const void *a, const void *b); + #define vec_at(v, i) (v)->elements[(i)] #define vec_len(v) (v)->length diff --git a/src/vector.c b/src/vector.c index 9477b6a..c46d9a9 100644 --- a/src/vector.c +++ b/src/vector.c @@ -125,3 +125,49 @@ int vec_shrink(Vector *vec) { return 0; } + +const void *vec_min(const Vector *vec, int(*cmp)(const void *a, const void *b)) { + void *a = vec->elements[0]; + for (size_t i = 1; i < vec_len(vec); ++i) { + if (!cmp(a, vec->elements[i])) { + a = vec->elements[i]; + } + } + return a; +} + +const void *vec_max(const Vector *vec, int(*cmp)(const void *a, const void *b)) { + void *a = vec->elements[0]; + for (size_t i = 1; i < vec_len(vec); ++i) { + if (cmp(a, vec->elements[i])) { + a = vec->elements[i]; + } + } + return a; +} + +int vec_cmp_int(const void *a, const void *b) { + const int x = *(int*)a; + const int y = *(int*)b; + + if (x > y) { + return 1; + } + if (x < y) { + return -1; + } + return 0; +} + +int vec_cmp_char(const void *a, const void *b) { + const char x = *(int*)a; + const char y = *(int*)b; + + if (x > y) { + return 1; + } + if (x < y) { + return -1; + } + return 0; +} diff --git a/tests/tests.c b/tests/tests.c index 280391f..b0c9d93 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -227,6 +227,13 @@ void test_vector() { t = (int*)vec_at(v, 4); assert(*t == e4); + const int *min = vec_min(v, vec_cmp_int); + const int *max = vec_max(v, vec_cmp_int); + printf("min: %d\n", *min); + printf("max: %d\n", *max); + assert(*min == e0); + assert(*max == e4); + t = (int*)vec_remove(v, 1); assert(t != NULL); assert(*t == 1);