diff --git a/include/gp/algorithms/partition.hpp b/include/gp/algorithms/partition.hpp index 5a38995..0bf9284 100644 --- a/include/gp/algorithms/partition.hpp +++ b/include/gp/algorithms/partition.hpp @@ -4,18 +4,18 @@ namespace gp { template it_t lomuto_partition(it_t first, it_t last, pred predicate = pred{}) { - auto pivot = *--it_t(last); - auto i = --it_t(first); - for(auto j = first; j != last; ++j) { - if(!predicate(*j, pivot)){ + auto j = first; + ++j; + for(; j != last; ++j) { + if(predicate(*j)){ ++i; gp::swap(*i, *j); } } - return i; + return ++i; } template diff --git a/include/gp/algorithms/sort.hpp b/include/gp/algorithms/sort.hpp index 8597d22..3b3ff05 100644 --- a/include/gp/algorithms/sort.hpp +++ b/include/gp/algorithms/sort.hpp @@ -1,7 +1,6 @@ #pragma once #include #include -#include namespace gp { diff --git a/tests/partition_test.cpp b/tests/partition_test.cpp new file mode 100644 index 0000000..48d1b4c --- /dev/null +++ b/tests/partition_test.cpp @@ -0,0 +1,86 @@ +#include "gp/containers/array.hpp" +#include "gp/containers/vector.hpp" +#include "gp/algorithms/partition.hpp" +#include "test_scaffold.h" +#include "allocator.hpp" +#include + +#include +#include +#include +#include + +typedef std::mt19937_64 cheap_rand; + + + +struct partition_array_test : public test_scaffold { + uint32_t seed; + + partition_array_test() { + name = __FILE__ ":1_seed"; + seed = std::random_device{}(); + name += std::to_string(seed); + } + + virtual int run() { + cheap_rand setter(seed); + + for(int i = 0; i < 250; ++i) { + gp::array ary; + for(auto& elem : ary) { + elem = setter(); + } + + auto pivot = gp::hoare_partition(ary.begin(), ary.end(), [](const auto& v){return v % 2;}); + + for(auto it = ary.begin(); it != pivot;++it) { + gp_config::assertion(!!(*it % 2), "partition failed"); + } + + for(auto it = pivot; it != ary.end();++it) { + gp_config::assertion(!(*it % 2), "partition failed"); + } + } + + return 0; + } +}; + +append_test dummy_s5f468e43(new partition_array_test{}); + + +struct partition_array_lomuto_test : public test_scaffold { + uint32_t seed; + + partition_array_lomuto_test() { + name = __FILE__ ":2_seed"; + seed = std::random_device{}(); + name += std::to_string(seed); + } + + virtual int run() { + cheap_rand setter(seed); + + for(int i = 0; i < 250; ++i) { + gp::array ary; + for(auto& elem : ary) { + elem = setter(); + } + + auto pivot = gp::lomuto_partition(ary.begin(), ary.end(), [](const auto& v){return v % 2;}); + + for(auto it = ary.begin(); it != pivot;++it) { + gp_config::assertion(!!(*it % 2), "partition failed"); + } + + for(auto it = pivot; it != ary.end();++it) { + gp_config::assertion(!(*it % 2), "partition failed"); + } + } + + return 0; + } +}; + +append_test dummy_lcvudg8e43(new partition_array_lomuto_test{}); \ No newline at end of file