diff --git a/ypsu.cpp b/ypsu.cpp index 81d579f..63e24aa 100644 --- a/ypsu.cpp +++ b/ypsu.cpp @@ -144,6 +144,33 @@ void twopass(uint32_t *a, int n) { // --index // különben // ++pivot_index +/** + * Divides array into two partitions by its topmost bit. + * - Similar to quicksort partitioning, but changed accordingly. + * - MSB 0 bit values will come first partition. + * - The return value tells partition boundary. + * + * @param a The array to partition and occurence count. + * @param n The length of the array. + */ +static inline uint32_t bit_partition(uint32_t *a, uint32_t n) noexcept { + uint32_t i = -1; + uint32_t j = n; + + while(true) { + // Move past well-placed ones + do ++i; while (!(a[i] & 0x80)); + do --j; while (a[j] & 0x80); + + // If the indices crossed, return + if(i >= j) return j; + + // Swap badly placed + uint32_t tmp = a[i]; + a[i] = a[j]; + a[j] = tmp; + } +} template static inline uint32_t morgrab(uint32_t elem) noexcept { return (elem >> (8 * j)) & 0xff;