|
4 | 4 | */ |
5 | 5 | #include <forward_list> |
6 | 6 | #include <iterator> |
| 7 | +#include <random> |
7 | 8 | #include <vector> |
8 | 9 | #include <catch2/catch_test_macros.hpp> |
| 10 | +#include <rapidcheck.h> |
| 11 | +#include <rapidcheck/catch.h> |
9 | 12 | #include <cpp-sort/probes/exc.h> |
10 | 13 | #include <cpp-sort/utility/size.h> |
11 | 14 | #include <testing-tools/distributions.h> |
@@ -64,4 +67,24 @@ TEST_CASE( "measure of disorder: exc", "[probe][exc]" ) |
64 | 67 | CHECK( exc(seq) == 1 ); |
65 | 68 | CHECK( exc(subseq) == 2 ); |
66 | 69 | } |
| 70 | + |
| 71 | + // Property formalized by Estivill-Castro in *Sorting and Measures of Disorder*, |
| 72 | + // only works when X has distinct values |
| 73 | + |
| 74 | + rc::prop("Exc(XY) = Exc(X) + Exc(Y) if X ≤ Y", []() { |
| 75 | + using diff_t = std::vector<int>::difference_type; |
| 76 | + using param_t = std::uniform_int_distribution<diff_t>::param_type; |
| 77 | + |
| 78 | + auto sequence = *rc::gen::unique<std::vector<int>>(rc::gen::arbitrary<int>()); |
| 79 | + |
| 80 | + // Split the sequence into two consequent subsequences X and Y |
| 81 | + auto size = static_cast<diff_t>(sequence.size()); |
| 82 | + std::uniform_int_distribution<diff_t> dist; |
| 83 | + auto x_begin = sequence.begin(); |
| 84 | + auto y_begin = x_begin + dist(hasard::engine(), param_t{0, size}); |
| 85 | + std::nth_element(x_begin, y_begin, sequence.end()); |
| 86 | + |
| 87 | + using cppsort::probe::exc; |
| 88 | + return exc(sequence) == exc(x_begin, y_begin) + exc(y_begin, sequence.end()); |
| 89 | + }); |
67 | 90 | } |
0 commit comments