From 5f92d24de075a56ccdfa47c38a3bd465fe6f7435 Mon Sep 17 00:00:00 2001 From: Seoxi Ryouko Date: Fri, 21 Aug 2026 01:01:11 -0500 Subject: [PATCH] Added dependency-injected shuffle function --- libkeke_array.c | 11 ++++++++++- libkeke_array.h | 4 +++- libkeke_utils.c | 24 +++++++++++++++++------- libkeke_utils.h | 2 +- test_array.c | 13 +++++++++---- 5 files changed, 40 insertions(+), 14 deletions(-) diff --git a/libkeke_array.c b/libkeke_array.c index a4b18b2..418ea22 100644 --- a/libkeke_array.c +++ b/libkeke_array.c @@ -22,7 +22,7 @@ typedef struct { KekeArray *keke_array_alloc(size_t initial_len, size_t type_size) { KekeArray *array = malloc(sizeof(*array)); array->len = initial_len; - size_t max_len = next_power_of_two(initial_len); + size_t max_len = bit_ceil(initial_len); array->type_size = type_size; array->max_len = max_len; @@ -198,6 +198,15 @@ void keke_array_qsort_header(KekeArray *array, size_t start_header_size) { qsort_r(array->content, array->len, array->type_size, compar, &start_header_size); } +typedef int (*Rng_fun)(int); + +void keke_array_shuffle(KekeArray *array, Rng_fun rng) { + for(size_t i = 0; i < array->len; ++i) { + size_t j = rng(i + 1); + keke_swap(ARRAY_GET(array, i), ARRAY_GET(array, j), array->type_size); + } +} + // requires pre-sorted arrays KekeArray *keke_array_merge(KekeArray *a, KekeArray *b) { if(a->len == 0) { diff --git a/libkeke_array.h b/libkeke_array.h index 51a34bd..2bdf804 100644 --- a/libkeke_array.h +++ b/libkeke_array.h @@ -40,13 +40,15 @@ void keke_array_reverse(KekeArray *array); void keke_array_qsort(KekeArray *array); void keke_array_qsort_header(KekeArray *array, size_t start_header_size); KekeArray *keke_array_merge(KekeArray *a, KekeArray *b); +typedef int (*Rng_fun)(int); +void keke_array_shuffle(KekeArray *array, Rng_fun rng); typedef bool (*Test_func)(void *, size_t, KekeArray *); bool keke_array_some(KekeArray *array, Test_func test); bool keke_array_all(KekeArray *array, Test_func test); -void *keke_array_find_start(KekeArray *array, void *start, size_t size); void *keke_array_find(KekeArray *array, Test_func test); +void *keke_array_find_start(KekeArray *array, void *start, size_t size); KekeArray *keke_array_filter(KekeArray *array, Test_func test); diff --git a/libkeke_utils.c b/libkeke_utils.c index 009bd3b..798db44 100644 --- a/libkeke_utils.c +++ b/libkeke_utils.c @@ -1,17 +1,27 @@ #include void keke_swap(void *a, void *b, size_t size) { - char *aa = a; - char *bb = b; - for(size_t i = 0; i < size; i++) { + if(a == b) return; + size_t i = 0; + int *ia = a; + int *ib = b; + for(i = 0; i < (size / sizeof(int)); ++i) { + ia[i] ^= ib[i]; + ib[i] ^= ia[i]; + ia[i] ^= ib[i]; + } + size %= sizeof(int); + char *aa = a + (i * sizeof(int)); + char *bb = b + (i * sizeof(int)); + for(i = 0; i < size; i++) { aa[i] ^= bb[i]; bb[i] ^= aa[i]; aa[i] ^= bb[i]; } } -size_t next_power_of_two(size_t s) { - size_t t = 1; - while(t < s) t <<= 1; - return t; +size_t bit_ceil(size_t s) { + size_t t = 1; + while(t < s) t <<= 1; + return t; } diff --git a/libkeke_utils.h b/libkeke_utils.h index 05870fd..1eb4929 100644 --- a/libkeke_utils.h +++ b/libkeke_utils.h @@ -6,7 +6,7 @@ #define BOOL_PRETTY(b) (b ? "True" : "False") void keke_swap(void *, void *, size_t); -size_t next_power_of_two(size_t s); +size_t bit_ceil(size_t s); #endif diff --git a/test_array.c b/test_array.c index 0f7cb33..4ccfc6e 100644 --- a/test_array.c +++ b/test_array.c @@ -33,6 +33,10 @@ void add(void *vx, void *vacc) { *acc += *x; } +int rng(int x) { + return rand() % x; +} + int main(void) { KekeArray *array = keke_array_alloc(ARRAY_LEN, sizeof(int)); @@ -78,7 +82,7 @@ int main(void) { puts("\n"); keke_array_pop(array2, &j); - puts("Expected value:\n7, 7, 6, 5, 6,\t0"); + puts("Expected value:\n7, 7, 6, 5, 6,\t5"); keke_array_foreach(array2, output); printf("\t%d", j); puts("\n"); @@ -147,9 +151,10 @@ int main(void) { printf("Expected value:\n0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 5, 6, 7, 8, 9,\n"); keke_array_foreach(array5, output); puts("\n"); - keke_array_foreach(array, output); - puts("\n"); - keke_array_foreach(array2, output); + + keke_array_shuffle(array5, rng); + printf("Expected value:\n2, 0, 3, 7, 3, 1, 8, 2, 2, 1, 3, 5, 6, 2, 9, 4,\n"); + keke_array_foreach(array5, output); puts("\n"); keke_array_free(array);