diff --git a/examples/ex_4.c b/examples/ex_4.c index 3e2ca86..bafadda 100644 --- a/examples/ex_4.c +++ b/examples/ex_4.c @@ -86,9 +86,37 @@ print_array(int *array, size_t l) } bool -has_span(int *array, size_t n, int x, int l) +has_span(int *array, size_t l, size_t n) { - if (n == 0 || l <= 0) { + if (n == 0 || l == 0 || n > l) { + return false; + } + + int sorted[l]; + memcpy(sorted, array, sizeof(int) * l); + qsort(sorted, l, sizeof(int), compare_ints); + + for (size_t i = 0; i <= l - n; i++) { + if (sorted[i] + n - 1 == sorted[i + n - 1]) { +#if 0 + fprintf(stderr, "Found span: "); + for (size_t j = i; j < i + n; j++) { + fprintf(stderr, "%d ", sorted[j]); + } + fprintf(stderr, "\n"); +#endif + __diag("Found span: [%d, %d], length: %zu\n", sorted[i], sorted[i + n - 1], n); + return true; + } + } + + return false; +} + +bool +is_span(int *array, size_t n, int x, int l) +{ + if (n == 0 || l < 0) { return false; } @@ -105,7 +133,6 @@ has_span(int *array, size_t n, int x, int l) } } } - return false; // Span not found } @@ -113,11 +140,10 @@ void print_spans(int *array, size_t n) { int a[n]; - size_t start = 0; - size_t end = 0; + size_t start = 0, end = 0; if (n == 0) { - printf("Array is empty\n"); + fprintf(stderr, "Array is empty\n"); return; } @@ -130,9 +156,9 @@ print_spans(int *array, size_t n) } else { // Print the current span if (start == end) { - printf("[%d] ", a[start]); + fprintf(stderr, "[%d] ", a[start]); } else { - printf("[%d, %d] ", a[start], a[end]); + fprintf(stderr, "[%d, %d] ", a[start], a[end]); } // Move to the next span start = i; @@ -142,9 +168,9 @@ print_spans(int *array, size_t n) // Print the last span if needed if (start == end) { - printf("[%d]\n", a[start]); + fprintf(stderr, "[%d]\n", a[start]); } else { - printf("[%d, %d]\n", a[start], a[end]); + fprintf(stderr, "[%d, %d]\n", a[start], a[end]); } } @@ -173,15 +199,68 @@ main(void) setbuf(stdout, 0); setbuf(stderr, 0); - // int foo[] = {1, 2, 3, 5, 7, 8 ,9, 10, 21}; - // print_spans(foo, sizeof(foo) / sizeof(foo[0])); - // exit(0); - - // start with a 1KiB buffer, TEST_ARRAY_SIZE bits - uint8_t *buf = calloc(TEST_ARRAY_SIZE * 3, sizeof(uint8_t)); + // start with a 3KiB buffer, TEST_ARRAY_SIZE bits + uint8_t *buf = calloc(3 * 1024, sizeof(uint8_t)); // create the sparse bitmap - sparsemap_t *map = sparsemap(buf, sizeof(uint8_t) * 1024 * 3, 0); + sparsemap_t *map = sparsemap(buf, sizeof(uint8_t) * 3 * 1024, 0); + + // seed the PRNG +#ifdef SEED + __random_seed(&prng, 8675309); +#else + __random_seed(&prng, (unsigned int)time(NULL) ^ getpid()); +#endif + + for (i = 0; i < TEST_ARRAY_SIZE; i++) { + uint32_t r = __random(&prng); + array[i] = (int)r % (4 * TEST_ARRAY_SIZE); + if (array[i] < 0) { + i--; + } + for (int j = 0; j < i; j++) { + if (array[j] == array[i]) { + i--; + } + } + } + // create a span of at least 8 for testing between 141 and 153 + int j = 143; + for (i = 0; i < 8; i++) { + uint32_t r = __random(&prng) % TEST_ARRAY_SIZE; + array[r] = j++; + } + // randomize setting the bits on + shuffle(&prng, array, TEST_ARRAY_SIZE); + print_spans(array, TEST_ARRAY_SIZE); + + // set all the bits on in a random order + for (i = 0; i < TEST_ARRAY_SIZE; i++) { + //__diag("set %d\n", array[i]); + sparsemap_set(map, array[i], true); + assert(sparsemap_is_set(map, array[i]) == true); + } + + for (size_t len = 1; len < TEST_ARRAY_SIZE; len++) { + // for (size_t len = 1; len <= 1; len++) { + // for (size_t len = 2; len <= 2; len++) { + // for (size_t len = 3; len <= 3; len++) { + // for (size_t len = 8; len <= 8; len++) { + __diag("================> %lu\n", len); + has_span(array, TEST_ARRAY_SIZE, len); + size_t l = sparsemap_span(map, 0, len); + __diag("Found span in map starting at %lu of length %lu\n", l, len); + __diag("is_span(%lu, %lu) == %s\n", l, len, is_span(array, TEST_ARRAY_SIZE, l, len) ? "yes" : "no"); + i = (int)l; + do { + bool set = sparsemap_is_set(map, i); + if (set) { + __diag("verified %d was set\n", i); + } else { + __diag("darn, %d was not really set, %s\n", i, was_set(i, array) ? "but we thought it was" : "because it wasn't"); + } + } while (++i < l + len); + } #if 0 for (i = 0; i < 8; i++) sparsemap_set(map, i, true); @@ -230,60 +309,5 @@ main(void) sparsemap_clear(map); #endif - // seed the PRNG -#ifdef SEED - __random_seed(&prng, 8675309); -#else - __random_seed(&prng, (unsigned int)time(NULL) ^ getpid()); -#endif - - for (i = 0; i < TEST_ARRAY_SIZE; i++) { - uint32_t r = __random(&prng); - array[i] = (int)r % (4 * TEST_ARRAY_SIZE); - if (array[i] < 0) { - i--; - } - for (int j = 0; j < i; j++) { - if (array[j] == array[i]) { - i--; - } - } - } - // create a span of at least 8 for testing between 141 and 153 - int j = 143; - for (i = 0; i < 8; i++) { - uint32_t r = __random(&prng) % TEST_ARRAY_SIZE; - array[r] = j++; - } - // randomize setting the bits on - shuffle(&prng, array, TEST_ARRAY_SIZE); - print_spans(array, TEST_ARRAY_SIZE); - - // set all the bits on in a random order - for (i = 0; i < TEST_ARRAY_SIZE; i++) { - //__diag("set %d\n", array[i]); - sparsemap_set(map, array[i], true); - assert(sparsemap_is_set(map, array[i]) == true); - } - - for (size_t len = 0; len < TEST_ARRAY_SIZE; len++) { - //for (size_t len = 1; len <= 1; len++) { - //for (size_t len = 2; len <= 2; len++) { - //for (size_t len = 3; len <= 3; len++) { - //for (size_t len = 8; len <= 8; len++) { - __diag("================> %lu\n", len); - size_t l = sparsemap_span(map, 0, len); - __diag("found span of %lu at %lu\n", len, l); - __diag("is_span(%lu, %lu) == %s\n", l, len, has_span(array, TEST_ARRAY_SIZE, l, len) ? "yes" : "no"); - for (i = (int)l; i < l + len; i++) { - bool set = sparsemap_is_set(map, i); - if (set) { - __diag("verified %d was set\n", i); - } else { - __diag("darn, %d was not really set, %s\n", i, was_set(i, array) ? "but we thought it was" : "because it wasn't"); - } - } - } - return 0; }