// Copyright Evgeny Panasyuk 2013.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://w...content-available-to-author-only...t.org/LICENSE_1_0.txt)
#include <functional>
#include <algorithm>
#include <stdexcept>
#include <iterator>
#include <iostream>
#include <cassert>
#include <cstddef>
#include <string>
#include <vector>
using namespace std;
template<typename Iterator>
using ValueType = typename iterator_traits<Iterator>::value_type;
template<typename I, typename P = less<ValueType<I>>>
/*
requires
(
ForwardIterator(I) && Mutable(I) &&
StrictWeakOrdering(P) && Domain(P) == ValueType(I)
)
*/
void quick_sort(I first, I last, P p = P())
{
while(first != last)
{
// naive version
auto pivot = *first;
auto first_not_less = partition(first, last, bind2nd(p, pivot));
quick_sort(first, first_not_less, p);
first = partition(first_not_less, last, not1(bind1st(p, pivot)));
}
}
/************************************************************************/
// Generates sorted sequences of given size isomorphic under ordering relation
// to all other sorted sequences of that size.
// Note, for integer sortings, distance between numbers would also make difference,
// not just "order".
template<typename I, typename T, typename F>
/*
requires
(
ForwardIterator(I) && Mutable(I) &&
Integer(T) && ValueType(I) == T &&
NullaryFunction(F)
)
*/
void generate_sorted_sequences(I first, I last, T x, F yield)
{
/*
For n=3 generates:
0 1 2
0 1 1
0 0 1
0 0 0
*/
if(first == last) yield();
else do
{
*first = x;
++first;
generate_sorted_sequences(first, last, x + 1, yield);
} while(first != last);
}
template<typename I1, typename I2, typename N>
/*
requires
(
ForwardIterator(I1) && InputIterator(I2) &&
ValueType(I1) == ValueType(I2) &&
EqualityComparable( ValueType(I1) ) &&
Integer(N)
)
*/
void require_equal(I1 first1, I1 last1, I2 first2, N n)
{
if(equal(first1, last1, first2)) return;
cout << "sequence #" << n << ", postcondition does not hold: ";
copy(first1, last1, ostream_iterator<int>(cout, " "));
cout << endl;
throw logic_error("fix the code");
}
template<typename T, typename F>
/*
Regular(T) && SortFunction(F)
*/
void test_sort(unsigned N, F sort)
{
vector<T> v(N), permutation, tmp;
size_t total = 0;
for(auto first=begin(v), last=first; last!=end(v); ++last)
{
generate_sorted_sequences(first, last, T{}, [&]
{
assert(is_sorted(first, last));
permutation.assign(first, last);
do
{
tmp = permutation;
sort(begin(tmp), end(tmp));
require_equal(begin(tmp), end(tmp), first, total);
++total;
} while(next_permutation(begin(permutation), end(permutation)));
});
cout << "tested " << total << " sequences" << endl;
}
}
/************************************************************************/
struct QuickSort
{
const string name = "Quicksort";
template<typename I>
void operator()(I first, I last) const
{
quick_sort(first, last);
}
};
struct StdSort
{
const string name = "std::sort";
template<typename I>
void operator()(I first, I last) const
{
sort(first, last);
}
};
struct StdStableSort
{
const string name = "std::stable_sort";
template<typename I>
void operator()(I first, I last) const
{
stable_sort(first, last);
}
};
struct StdParialSort
{
const string name = "std::partial_sort";
template<typename I>
void operator()(I first, I last) const
{
partial_sort(first, last, last);
}
};
/************************************************************************/
template<typename SortFunction>
void test()
{
SortFunction f;
cout << "Testing " << f.name << endl;
test_sort<int>(10, f);
cout << string(32, '_') << endl;
}
template<typename SortFunction, typename Head, typename ...Tail>
void test()
{
test<SortFunction>();
test<Head, Tail...>();
}
int main()
{
test<QuickSort, StdSort, StdStableSort, StdParialSort>();
}
Ly8gQ29weXJpZ2h0IEV2Z2VueSBQYW5hc3l1ayAyMDEzLgovLyBEaXN0cmlidXRlZCB1bmRlciB0aGUgQm9vc3QgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAxLjAuCi8vIChTZWUgYWNjb21wYW55aW5nIGZpbGUgTElDRU5TRV8xXzAudHh0IG9yIGNvcHkgYXQKLy8gaHR0cDovL3cuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLnQub3JnL0xJQ0VOU0VfMV8wLnR4dCkKCiNpbmNsdWRlIDxmdW5jdGlvbmFsPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8c3RkZXhjZXB0PgojaW5jbHVkZSA8aXRlcmF0b3I+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPGNhc3NlcnQ+CiNpbmNsdWRlIDxjc3RkZGVmPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dmVjdG9yPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnRlbXBsYXRlPHR5cGVuYW1lIEl0ZXJhdG9yPgp1c2luZyBWYWx1ZVR5cGUgPSB0eXBlbmFtZSBpdGVyYXRvcl90cmFpdHM8SXRlcmF0b3I+Ojp2YWx1ZV90eXBlOwoKdGVtcGxhdGU8dHlwZW5hbWUgSSwgdHlwZW5hbWUgUCA9IGxlc3M8VmFsdWVUeXBlPEk+Pj4KLyoKcmVxdWlyZXMKKAogICAgRm9yd2FyZEl0ZXJhdG9yKEkpICYmIE11dGFibGUoSSkgJiYKICAgIFN0cmljdFdlYWtPcmRlcmluZyhQKSAmJiBEb21haW4oUCkgPT0gVmFsdWVUeXBlKEkpCikKKi8Kdm9pZCBxdWlja19zb3J0KEkgZmlyc3QsIEkgbGFzdCwgUCBwID0gUCgpKQp7CiAgICB3aGlsZShmaXJzdCAhPSBsYXN0KQogICAgewogICAgICAgIC8vIG5haXZlIHZlcnNpb24KICAgICAgICBhdXRvIHBpdm90ID0gKmZpcnN0OwogICAgICAgIGF1dG8gZmlyc3Rfbm90X2xlc3MgPSBwYXJ0aXRpb24oZmlyc3QsIGxhc3QsIGJpbmQybmQocCwgcGl2b3QpKTsKICAgICAgICBxdWlja19zb3J0KGZpcnN0LCBmaXJzdF9ub3RfbGVzcywgcCk7CiAgICAgICAgZmlyc3QgPSBwYXJ0aXRpb24oZmlyc3Rfbm90X2xlc3MsIGxhc3QsIG5vdDEoYmluZDFzdChwLCBwaXZvdCkpKTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8vIEdlbmVyYXRlcyBzb3J0ZWQgc2VxdWVuY2VzIG9mIGdpdmVuIHNpemUgaXNvbW9ycGhpYyB1bmRlciBvcmRlcmluZyByZWxhdGlvbgovLyAgICB0byBhbGwgb3RoZXIgc29ydGVkIHNlcXVlbmNlcyBvZiB0aGF0IHNpemUuCi8vIE5vdGUsIGZvciBpbnRlZ2VyIHNvcnRpbmdzLCBkaXN0YW5jZSBiZXR3ZWVuIG51bWJlcnMgd291bGQgYWxzbyBtYWtlIGRpZmZlcmVuY2UsCi8vICAgbm90IGp1c3QgIm9yZGVyIi4KdGVtcGxhdGU8dHlwZW5hbWUgSSwgdHlwZW5hbWUgVCwgdHlwZW5hbWUgRj4KLyoKcmVxdWlyZXMKKAogICAgRm9yd2FyZEl0ZXJhdG9yKEkpICYmIE11dGFibGUoSSkgJiYKICAgIEludGVnZXIoVCkgJiYgVmFsdWVUeXBlKEkpID09IFQgJiYgCiAgICBOdWxsYXJ5RnVuY3Rpb24oRikKKQoqLwp2b2lkIGdlbmVyYXRlX3NvcnRlZF9zZXF1ZW5jZXMoSSBmaXJzdCwgSSBsYXN0LCBUIHgsIEYgeWllbGQpCnsKICAgIC8qCiAgICAgICAgRm9yIG49MyBnZW5lcmF0ZXM6CiAgICAgICAgMCAxIDIKICAgICAgICAwIDEgMQogICAgICAgIDAgMCAxCiAgICAgICAgMCAwIDAKICAgICovCiAgICBpZihmaXJzdCA9PSBsYXN0KSB5aWVsZCgpOwogICAgZWxzZSBkbwogICAgewogICAgICAgICpmaXJzdCA9IHg7CiAgICAgICAgKytmaXJzdDsKICAgICAgICBnZW5lcmF0ZV9zb3J0ZWRfc2VxdWVuY2VzKGZpcnN0LCBsYXN0LCB4ICsgMSwgeWllbGQpOwogICAgfSB3aGlsZShmaXJzdCAhPSBsYXN0KTsKfQoKCnRlbXBsYXRlPHR5cGVuYW1lIEkxLCB0eXBlbmFtZSBJMiwgdHlwZW5hbWUgTj4KLyoKcmVxdWlyZXMKKAogICAgRm9yd2FyZEl0ZXJhdG9yKEkxKSAmJiBJbnB1dEl0ZXJhdG9yKEkyKSAmJgogICAgVmFsdWVUeXBlKEkxKSA9PSBWYWx1ZVR5cGUoSTIpICYmCiAgICBFcXVhbGl0eUNvbXBhcmFibGUoIFZhbHVlVHlwZShJMSkgKSAmJgogICAgSW50ZWdlcihOKQopCiovCnZvaWQgcmVxdWlyZV9lcXVhbChJMSBmaXJzdDEsIEkxIGxhc3QxLCBJMiBmaXJzdDIsIE4gbikKewogICAgaWYoZXF1YWwoZmlyc3QxLCBsYXN0MSwgZmlyc3QyKSkgcmV0dXJuOwoKICAgIGNvdXQgPDwgInNlcXVlbmNlICMiIDw8IG4gPDwgIiwgcG9zdGNvbmRpdGlvbiBkb2VzIG5vdCBob2xkOiAiOwogICAgY29weShmaXJzdDEsIGxhc3QxLCBvc3RyZWFtX2l0ZXJhdG9yPGludD4oY291dCwgIiAiKSk7CiAgICBjb3V0IDw8IGVuZGw7CiAgICB0aHJvdyBsb2dpY19lcnJvcigiZml4IHRoZSBjb2RlIik7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEY+Ci8qCiAgICBSZWd1bGFyKFQpICYmIFNvcnRGdW5jdGlvbihGKQoqLwp2b2lkIHRlc3Rfc29ydCh1bnNpZ25lZCBOLCBGIHNvcnQpCnsKICAgIHZlY3RvcjxUPiB2KE4pLCBwZXJtdXRhdGlvbiwgdG1wOwogICAgc2l6ZV90IHRvdGFsID0gMDsKICAgIGZvcihhdXRvIGZpcnN0PWJlZ2luKHYpLCBsYXN0PWZpcnN0OyBsYXN0IT1lbmQodik7ICsrbGFzdCkKICAgIHsKICAgICAgICBnZW5lcmF0ZV9zb3J0ZWRfc2VxdWVuY2VzKGZpcnN0LCBsYXN0LCBUe30sIFsmXQogICAgICAgIHsKICAgICAgICAgICAgYXNzZXJ0KGlzX3NvcnRlZChmaXJzdCwgbGFzdCkpOwogICAgICAgICAgICBwZXJtdXRhdGlvbi5hc3NpZ24oZmlyc3QsIGxhc3QpOwogICAgICAgICAgICBkbwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0bXAgPSBwZXJtdXRhdGlvbjsKICAgICAgICAgICAgICAgIHNvcnQoYmVnaW4odG1wKSwgZW5kKHRtcCkpOwogICAgICAgICAgICAgICAgcmVxdWlyZV9lcXVhbChiZWdpbih0bXApLCBlbmQodG1wKSwgZmlyc3QsIHRvdGFsKTsKICAgICAgICAgICAgICAgICsrdG90YWw7CiAgICAgICAgICAgIH0gd2hpbGUobmV4dF9wZXJtdXRhdGlvbihiZWdpbihwZXJtdXRhdGlvbiksIGVuZChwZXJtdXRhdGlvbikpKTsKICAgICAgICB9KTsKICAgICAgICBjb3V0IDw8ICJ0ZXN0ZWQgIiA8PCB0b3RhbCA8PCAiIHNlcXVlbmNlcyIgPDwgZW5kbDsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RydWN0IFF1aWNrU29ydAp7CiAgICBjb25zdCBzdHJpbmcgbmFtZSA9ICJRdWlja3NvcnQiOwogICAgdGVtcGxhdGU8dHlwZW5hbWUgST4KICAgIHZvaWQgb3BlcmF0b3IoKShJIGZpcnN0LCBJIGxhc3QpIGNvbnN0CiAgICB7CiAgICAgICAgcXVpY2tfc29ydChmaXJzdCwgbGFzdCk7CiAgICB9Cn07CnN0cnVjdCBTdGRTb3J0CnsKICAgIGNvbnN0IHN0cmluZyBuYW1lID0gInN0ZDo6c29ydCI7CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBJPgogICAgdm9pZCBvcGVyYXRvcigpKEkgZmlyc3QsIEkgbGFzdCkgY29uc3QKICAgIHsKICAgICAgICBzb3J0KGZpcnN0LCBsYXN0KTsKICAgIH0KfTsKc3RydWN0IFN0ZFN0YWJsZVNvcnQKewogICAgY29uc3Qgc3RyaW5nIG5hbWUgPSAic3RkOjpzdGFibGVfc29ydCI7CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBJPgogICAgdm9pZCBvcGVyYXRvcigpKEkgZmlyc3QsIEkgbGFzdCkgY29uc3QKICAgIHsKICAgICAgICBzdGFibGVfc29ydChmaXJzdCwgbGFzdCk7CiAgICB9Cn07CnN0cnVjdCBTdGRQYXJpYWxTb3J0CnsKICAgIGNvbnN0IHN0cmluZyBuYW1lID0gInN0ZDo6cGFydGlhbF9zb3J0IjsKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEk+CiAgICB2b2lkIG9wZXJhdG9yKCkoSSBmaXJzdCwgSSBsYXN0KSBjb25zdAogICAgewogICAgICAgIHBhcnRpYWxfc29ydChmaXJzdCwgbGFzdCwgbGFzdCk7CiAgICB9Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdGVtcGxhdGU8dHlwZW5hbWUgU29ydEZ1bmN0aW9uPgp2b2lkIHRlc3QoKQp7CiAgICBTb3J0RnVuY3Rpb24gZjsKICAgIGNvdXQgPDwgIlRlc3RpbmcgIiA8PCBmLm5hbWUgPDwgZW5kbDsKICAgIHRlc3Rfc29ydDxpbnQ+KDEwLCBmKTsKICAgIGNvdXQgPDwgc3RyaW5nKDMyLCAnXycpIDw8IGVuZGw7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIFNvcnRGdW5jdGlvbiwgdHlwZW5hbWUgSGVhZCwgdHlwZW5hbWUgLi4uVGFpbD4Kdm9pZCB0ZXN0KCkKewogICAgdGVzdDxTb3J0RnVuY3Rpb24+KCk7CiAgICB0ZXN0PEhlYWQsIFRhaWwuLi4+KCk7Cn0KCmludCBtYWluKCkKewogICAgdGVzdDxRdWlja1NvcnQsIFN0ZFNvcnQsIFN0ZFN0YWJsZVNvcnQsIFN0ZFBhcmlhbFNvcnQ+KCk7Cn0K