Playing with C++17 via solving "Cracking the Coding Interview" questions.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cxx17/cx_shuffle.cc

68 lines
1.5 KiB

// 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");
}