diff --git a/data.hpp b/data.hpp index cdf0e33..45739f1 100644 --- a/data.hpp +++ b/data.hpp @@ -342,16 +342,16 @@ namespace asp { constexpr ArgVal(const size_t& _i, const T& _v) noexcept : indice(_i), val(_v) {} constexpr bool operator>(const ArgVal& other) const noexcept { - return std::move(val > other.val); + return val > other.val; } constexpr bool operator<(const ArgVal& other) const noexcept { - return std::move(val < other.val); + return val < other.val; } constexpr bool operator>=(const ArgVal& other) const noexcept { - return std::move(val >= other.val); + return val >= other.val; } constexpr bool operator<=(const ArgVal& other) const noexcept { - return std::move(val <= other.val); + return val <= other.val; } }; @@ -400,17 +400,12 @@ namespace asp { return ArgVal(i, a[i]); }); - mergesort(temp_vals, l, r); + mergesort(temp_vals, 0, a.length - 1); Array indices(a.length); - return std::move(map(indices, [&temp_vals](const size_t& i, const size_t&) -> size_t { + return map(indices, [&temp_vals](const size_t& i, const size_t&) -> size_t { return temp_vals[i].indice; - })); - } - - template - Array mergesort_arg(const Array& a) noexcept { - return mergesort_arg(a, 0, a.length - 1); + }); } template @@ -440,108 +435,49 @@ namespace asp { } template - Array counting_sort_arg(const Array& a) noexcept { - Array indices = range(a.length); - - return indices; - } - - inline void countsort(int a[], int n, int pos){ - int* output = new int[n + 1]; - int max = (a[0] / pos) % 10; - for (int i = 1; i < n; i++) { - if (((a[i] / pos) % 10) > max) - max = a[i]; + inline void countsort(Array& a, int64_t k, int64_t pos) noexcept { + Array output(a.length + 1); + T max = T((a[0] / pos) % k); + for (size_t i = 1; i < a.length; ++i) { + const T val = a[i]; + if (((val / pos) % k) > max) + max = val; } - int* count = new int[max + 1]; - for (int i = 0; i < max; ++i) - count[i] = 0; - for (int i = 0; i < n; i++) - count[(a[i] / pos) % 10]++; - for (int i = 1; i < 10; i++) + + Array count(max + 1); + memset(count.data, 0, count.length * sizeof(T)); + + for (size_t i = 0; i < a.length; ++i) + ++count[size_t((a[i] / pos) % k)]; + + // Prefix sum + for (size_t i = 1; i < count.length; i++) count[i] += count[i - 1]; - for (int i = n - 1; i >= 0; i--) { - output[count[(a[i] / pos) % 10] - 1] = a[i]; - count[(a[i] / pos) % 10]--; + + for (size_t i = a.length - 1; i > 0; --i) { + const T val = a[i]; + output[count[size_t((val / pos) % k)] - 1] = val; + --count[size_t((val / pos) % k)]; } - for (int i = 0; i < n; i++) - a[i] = output[i]; - - delete[] output; - delete[] count; - } - - // template - // constexpr void radix_sort_256(T* a, const size_t& n) noexcept { - // //template - // //void radix_sort(const Array& a) noexcept { - // if (n <= 1) - // //if (a.length <= 1) - // return; - // - // T* output = new T[n]; // output array - // size_t* const count = new size_t[256]; - // T* originalArr = a; // So we know which was input - // - // for (size_t shift = 0, s = 0; shift < 4; shift++, s += 8) { - // // Zero the counts - // for (size_t i = 0; i < 256; i++) - // count[i] = 0; - // - // // Store count of occurrences in count[] - // for (size_t i = 0; i < n; i++) - // count[(a[i] >> s) & 0xff]++; - // - // // Change count[i] so that count[i] now contains - // // actual position of this digit in output[] - // for (size_t i = 1; i < 256; i++) - // count[i] += count[i - 1]; - // - // // Build the output array - // for (int32_t i = n - 1; i >= 0; i--) { - // // precalculate the offset as it's a few instructions - // const size_t idx = (a[i] >> s) & 0xff; - // - // // Subtract from the count and store the value - // output[--count[idx]] = a[i]; - // } - // - // // Copy the output array to input[], so that input[] - // // is sorted according to current digit - // - // // We can just swap the pointers - // swap(a, output); - // } - // - // // If we switched posize_ters an odd number of times, - // // make sure we copy before returning - // if (originalArr == output) { - // swap(a, output); - // for (size_t i = 0; i < n; i++) - // a[i] = output[i]; - // } - // - // delete[] output, delete[] count; - // } - - constexpr void radix_sort_256(int32_t a[], int n){ - int max = a[0]; - for (int i = 1; i < n; i++) - if (a[i] > max) - max = a[i]; - for (int pos = 1; max / pos > 0; pos *= 10) - countsort(a, n, pos); + const T val = a[0]; + output[count[size_t((val / pos) % k)] - 1] = val; + --count[size_t((val / pos) % k)]; + memmove(a.data, output.data, a.length * sizeof(T)); } template - constexpr void radix_sort(const Array& a) noexcept { - radix_sort_256(a.data.get(), a.length); + inline void counting_sort(Array& a) noexcept { + countsort(a, max(a) + 1, 1); } - // template - // constexpr Array radix_sort_arg(const Array& a) noexcept { - // Array indices = range(a.length); - // - // return indices; - // } + template + constexpr void radix_sort(Array& a) noexcept { + constexpr int64_t k = 10; + T max = a[0]; + for (size_t i = 1; i < a.length; i++) + if (a[i] > max) + max = a[i]; + for (int64_t pos = 1; max / pos > 0; pos *= k) + countsort(a, k, pos); + } };