diff --git a/Tests/AK/CMakeLists.txt b/Tests/AK/CMakeLists.txt index cab724ee365..408c4575a38 100644 --- a/Tests/AK/CMakeLists.txt +++ b/Tests/AK/CMakeLists.txt @@ -58,6 +58,7 @@ set(AK_TEST_SOURCES TestOwnPtr.cpp TestPrint.cpp TestQueue.cpp + TestQuickSelect.cpp TestQuickSort.cpp TestRedBlackTree.cpp TestRefPtr.cpp diff --git a/Tests/AK/TestQuickSelect.cpp b/Tests/AK/TestQuickSelect.cpp new file mode 100644 index 00000000000..56bf7b71696 --- /dev/null +++ b/Tests/AK/TestQuickSelect.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +#include +#include + +template +int naive_select(Collection& a, int k) +{ + quick_sort(a); + return k; +} + +TEST_CASE(quickselect_inplace) +{ + + // Test the various Quickselect Pivot methods against the naive select + Array array; + Array naive_results; + + auto reset_array = [&]() { + for (size_t i = 0; i < 64; ++i) + array[i] = (64 - i) % 32 + 32; + }; + + // Populate naive results + reset_array(); + for (size_t k = 0; k < 64; ++k) { + naive_results[k] = array.at(naive_select(array, k)); + } + + // Default configuration of `quick_select` + reset_array(); + for (size_t k = 0; k < 64; ++k) { + EXPECT(naive_results[k] == array.at(AK::quickselect_inplace(array, k))); + } + + // first_element pivot function + reset_array(); + for (size_t k = 0; k < 64; ++k) { + EXPECT(naive_results[k] == array.at(AK::quickselect_inplace(array, k, [](auto collection, size_t left, size_t right, auto less_than) { return AK::PivotFunctions::first_element(collection, left, right, less_than); }))); + } + + // middle_element pivot function + reset_array(); + for (size_t k = 0; k < 64; ++k) { + EXPECT(naive_results[k] == array.at(AK::quickselect_inplace(array, k, [](auto collection, size_t left, size_t right, auto less_than) { return AK::PivotFunctions::middle_element(collection, left, right, less_than); }))); + } + + // random_element pivot function + reset_array(); + for (size_t k = 0; k < 64; ++k) { + EXPECT(naive_results[k] == array.at(AK::quickselect_inplace(array, k, [](auto collection, size_t left, size_t right, auto less_than) { return AK::PivotFunctions::random_element(collection, left, right, less_than); }))); + } + + // median_of_medians pivot function + reset_array(); + for (size_t k = 0; k < 64; ++k) { + EXPECT(naive_results[k] == array.at(AK::quickselect_inplace(array, k, [](auto collection, size_t left, size_t right, auto less_than) { return AK::PivotFunctions::median_of_medians(collection, left, right, less_than); }))); + } +}