#include #include #include #include #include #include #include class Dice { std::vector sides; std::vector probs; std::mt19937 gen; std::discrete_distribution<> dist; public: size_t accepted = 0; size_t rejected = 0; Dice(const std::vector& sides, const std::vector& probs) : sides(sides), probs(probs), gen(std::random_device{}()), dist(probs.begin(), probs.end()) {} std::string fair_dice() { while (true) { std::vector res; for (size_t i = 0; i < sides.size(); ++i) res.push_back(sides[dist(gen)]); std::set uniq(res.begin(), res.end()); if (uniq.size() == res.size()) { ++accepted; return res[0]; } ++rejected; } } std::map throw_dice(int n) { std::map res; for (auto& s : sides) res[s] = 0; for (int i = 0; i < n; ++i) res[fair_dice()]++; return res; } std::pair stats() const { return {accepted, rejected}; } void reset_stats() { accepted = rejected = 0; } }; namespace py = pybind11; PYBIND11_MODULE(dice, m) { py::class_(m, "Dice") .def(py::init&, const std::vector&>()) .def("fair_dice", &Dice::fair_dice) .def("throw_dice", &Dice::throw_dice) .def("stats", &Dice::stats) .def("reset_stats", &Dice::reset_stats) .def_readwrite("accepted", &Dice::accepted) .def_readwrite("rejected", &Dice::rejected); }