68 lines
1.5 KiB
C++
68 lines
1.5 KiB
C++
// An iterator that shuffles over a vector.
|
|
|
|
#define CATCH_CONFIG_MAIN
|
|
#include <catch.hpp>
|
|
|
|
#include <experimental/string_view>
|
|
#include <sstream>
|
|
#include <vector>
|
|
#include <range/v3/all.hpp>
|
|
#include <cstdlib>
|
|
|
|
using string_view = std::experimental::string_view;
|
|
|
|
// Should work over any SequenceContainer.
|
|
template <typename Container>
|
|
std::string join(const Container& vect, string_view sep = " ") {
|
|
auto i = 0;
|
|
std::stringstream out;
|
|
|
|
for (const auto& item : vect) {
|
|
if (i != 0) {
|
|
out << sep;
|
|
}
|
|
out << item;
|
|
i++;
|
|
}
|
|
|
|
return out.str();
|
|
}
|
|
|
|
template <typename Container>
|
|
Container shuffle_1(const Container& src) {
|
|
using pair = std::pair<size_t, int>;
|
|
std::vector<pair> indexes;
|
|
int i = 0;
|
|
|
|
for (size_t i = 0; i < src.size(); i++) {
|
|
indexes.emplace_back(pair{i, std::rand()});
|
|
}
|
|
std::cout << join(indexes | ranges::view::keys) << "\n";
|
|
|
|
std::sort(indexes.begin(), indexes.end(), [](auto lhs, auto rhs) { return lhs.second < rhs.second; });
|
|
|
|
Container out;
|
|
for (auto key : indexes | ranges::view::keys) {
|
|
out.emplace_back(src[key]);
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
template <typename Container>
|
|
Container shuffle(const Container& src) {
|
|
Container dup{src};
|
|
|
|
for (size_t i = 0; i < src.size(); i++) {
|
|
std::swap(dup[i], dup[std::rand() % src.size()]);
|
|
}
|
|
|
|
return dup;
|
|
}
|
|
|
|
TEST_CASE("cx_shuffle", "shuffle") {
|
|
std::vector<int> items{1, 2, 3, 4, 5, 6};
|
|
|
|
CHECK(join(items) == "1 2 3 4 5 6");
|
|
CHECK(join(shuffle(items)) == "2 1 4 5 6 3");
|
|
}
|