2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
45
46
47
48
53
54
56inline void throw_assertion_error(
const std::string &condition,
57 const std::string &msg) {
58 throw std::runtime_error(
"tgen: " + msg +
" (assertion `" + condition +
61inline void throw_assertion_error(
const std::string &condition) {
62 throw std::runtime_error(
"tgen: assertion `" + condition +
"` failed");
64inline std::runtime_error error(
const std::string &msg) {
65 return std::runtime_error(
"tgen: " + msg);
67inline std::runtime_error contradiction_error(
const std::string &type,
68 const std::string &msg =
"") {
70 std::string error_msg =
71 type +
": invalid " + type +
" (contradicting restrictions)";
73 error_msg +=
": " + msg;
74 return error(error_msg);
76inline std::runtime_error
77complex_restrictions_error(
const std::string &type,
78 const std::string &msg =
"") {
80 std::string error_msg =
81 type +
": cannot represent " + type +
" (complex restrictions)";
83 error_msg +=
": " + msg;
84 return error(error_msg);
86inline void tgen_ensure_against_bug(
bool cond,
const std::string &msg =
"") {
88 std::cerr <<
"tgen: " << msg << std::endl;
89 throw std::runtime_error(
90 "tgen: THERE IS A BUG IN TGEN; PLEASE CONTACT MAINTAINERS");
95#define tgen_ensure(cond, ...)
97 tgen::_detail::throw_assertion_error(#cond, ##__VA_ARGS__);
100inline bool registered =
false;
101inline void ensure_registered() {
103 "tgen was not registered! You should call "
104 "tgen::register_gen(argc, argv) before running tgen functions");
110template <
typename T,
typename =
void>
struct is_container : std::false_type {};
112struct is_container<T,
113 std::void_t<
typename std::remove_reference_t<T>::value_type,
114 decltype(std::begin(std::declval<T>())),
115 decltype(std::end(std::declval<T>()))>>
118template <
typename Char,
typename Traits,
typename Alloc>
119struct is_container<std::basic_string<Char, Traits, Alloc>> : std::false_type {
121template <
typename Char,
typename Traits,
typename Alloc>
122struct is_container<
const std::basic_string<Char, Traits, Alloc>>
123 : std::false_type {};
124template <
typename Char,
typename Traits,
typename Alloc>
125struct is_container<std::basic_string<Char, Traits, Alloc> &>
126 : std::false_type {};
127template <
typename Char,
typename Traits,
typename Alloc>
128struct is_container<
const std::basic_string<Char, Traits, Alloc> &>
129 : std::false_type {};
132template <
typename T>
struct is_pair : std::false_type {};
133template <
typename A,
typename B>
134struct is_pair<std::pair<A, B>> : std::true_type {};
136template <
typename T>
struct is_tuple : std::false_type {};
137template <
typename... Ts>
138struct is_tuple<std::tuple<Ts...>> : std::true_type {};
153template <
typename A,
typename B>
158template <
typename... Ts>
163
164
167using is_sequential_tag =
void;
170using has_subset_defined_tag =
void;
173
174
177inline std::mt19937 rng;
180template <
typename>
inline constexpr bool dependent_false_v =
false;
183
184
190 cpp_value(std::optional<
int> version = std::nullopt)
191 : version_(version ? *version : 0) {
193 tgen_ensure(*version == 17
or *version == 20
or *version == 23,
194 "unsupported C++ version (use 17, 20, 23)");
201
202
205enum class compiler_kind { gcc, clang, unknown };
208struct compiler_value {
213 compiler_value(compiler_kind kind = compiler_kind::unknown,
int major = 0,
215 : kind_(kind), major_(major), minor_(minor) {}
217inline compiler_value compiler;
222
223
226template <
typename T>
struct sequence;
229template <
typename Func,
typename... Args>
struct unique {
231 std::tuple<Args...> args_;
236 : func_(std::move(func)), args_(std::move(args)...) {}
240 auto generate_unique(
bool insert) {
241 for (
int i = 0; i < 84 * std::max<
int>(1, seen_.size()); ++i) {
242 T val = std::apply(func_, args_);
243 if (insert ? seen_.insert(val).second : seen_.count(val) == 0)
244 return std::optional<T>(val);
248 return std::optional<T>();
271 auto val = generate_unique(
true);
275 throw _detail::error(
"no more unique values");
277 template <
typename U>
auto gen(std::initializer_list<U> il) {
278 return gen(std::vector<U>(il));
284 for (
int i = 0; i < size; ++i)
285 res.push_back(gen());
287 return typename sequence<T>::instance(res);
293 bool empty() {
return generate_unique(
false) == std::nullopt; }
299 auto val = generate_unique(
true);
305 return typename sequence<T>::instance(res);
309 friend std::ostream &operator<<(std::ostream &out,
const unique &) {
310 static_assert(_detail::dependent_false_v<
unique>,
311 "cannot print a unique generator. Maybe you forgot to "
316template <
typename Func,
typename... Args>
317unique(Func, Args...) ->
unique<Func, Args...>;
321 const Gen &self()
const {
return *
static_cast<
const Gen *>(
this); }
323 template <
typename... Args>
auto gen_list(
int size, Args &&...args)
const {
324 std::vector<
typename Gen::instance> res;
326 for (
int i = 0; i < size; ++i)
327 res.push_back(
static_cast<
const Gen *>(
this)->gen(
328 std::forward<Args>(args)...));
330 return typename sequence<
typename Gen::instance>::instance(res);
334 template <
typename Pred,
typename... Args>
335 auto gen_until(Pred predicate,
int max_tries, Args &&...args)
const {
336 for (
int i = 0; i < max_tries; ++i) {
337 typename Gen::instance inst =
static_cast<
const Gen *>(
this)->gen(
338 std::forward<Args>(args)...);
344 throw _detail::error(
"could not generate instance matching predicate");
346 template <
typename Pred,
typename T,
typename... Args>
347 auto gen_until(Pred predicate,
int max_tries, std::initializer_list<T> il,
348 Args &&...args)
const {
349 return gen_until(predicate, max_tries, std::vector<T>(il),
350 std::forward<Args>(args)...);
354 template <
typename... Args>
auto unique(Args &&...args)
const {
356 [self = self()](
auto &&...inner_args)
mutable ->
decltype(
auto) {
358 std::forward<
decltype(inner_args)>(inner_args)...);
360 std::forward<Args>(args)...);
362 template <
typename T,
typename... Args>
363 auto unique(std::initializer_list<T> il, Args &&...args)
const {
364 return unique(std::vector<T>(il), std::forward<Args>(args)...);
368 friend std::ostream &operator<<(std::ostream &out,
const gen_base &) {
370 _detail::dependent_false_v<
gen_base>,
371 "cannot print a generator. Maybe you forgot to call `gen()`?");
378 const Inst &self()
const {
return *
static_cast<
const Inst *>(
this); }
381 return self().to_std() < rhs.to_std();
386
387
390template <
typename T,
typename =
void>
393struct is_associative_container<
394 T, std::void_t<
typename T::key_type,
typename T::key_compare>>
403template <
typename T,
typename =
void>
407 T, std::void_t<
typename std::decay_t<T>::tgen_is_sequential_tag>>
411template <
typename T,
typename =
void>
414struct has_subset_defined<
415 T, std::void_t<
typename std::decay_t<T>::tgen_has_subset_defined_tag>>
419
420
426 template <
typename T>
print(
const T &val,
char sep =
' ') {
427 std::ostringstream oss;
428 write(oss, val, sep);
431 template <
typename T>
432 print(
const std::initializer_list<T> &il,
char sep =
' ') {
433 std::ostringstream oss;
434 write(oss, std::vector<T>(il), sep);
437 template <
typename T>
438 print(
const std::initializer_list<std::initializer_list<T>> &il,
440 std::ostringstream oss;
441 std::vector<std::vector<T>> mat;
442 for (
const auto &i : il)
444 write(oss, mat, sep);
448 template <
typename T>
449 void write(std::ostream &os,
const T &val,
char sep =
' ') {
450 if constexpr (_detail::
is_pair<T>::value) {
452 write(os, val.first, sep);
454 write(os, val.second, sep);
456 write(os, val.first);
458 write(os, val.second);
460 }
else if constexpr (_detail::
is_tuple<T>::value)
461 write_tuple(os, val, sep);
462 else if constexpr (_detail::is_container<T>::value)
463 write_container(os, val, sep);
469 template <
typename C>
470 void write_container(std::ostream &os,
const C &container,
char sep =
' ') {
473 for (
const auto &e : container) {
482 template <
typename Tuple, size_t... I>
483 void write_tuple_impl(std::ostream &os,
const Tuple &tp,
char sep,
484 std::index_sequence<I...>) {
486 ((os << (first ? (first =
false,
"")
489 : std::string(1, sep))),
490 write(os, std::get<I>(tp),
494 template <
typename T>
495 void write_tuple(std::ostream &os,
const T &tp,
char sep =
' ') {
496 write_tuple_impl(os, tp, sep,
497 std::make_index_sequence<std::tuple_size<T>::value>{});
500 friend std::ostream &operator<<(std::ostream &out,
const print &pr) {
507 template <
typename T>
509 template <
typename T>
510 println(
const std::initializer_list<T> &il,
char sep =
' ')
512 template <
typename T>
513 println(
const std::initializer_list<std::initializer_list<T>> &il,
517 friend std::ostream &operator<<(std::ostream &out,
const println &pr) {
518 return out << pr.s_ <<
'\n';
523
524
528template <
typename T> T
next(T n) {
529 _detail::ensure_registered();
530 if constexpr (std::is_integral_v<T>) {
531 tgen_ensure(n >= 1,
"value for `next` bust be valid");
532 return std::uniform_int_distribution<T>(0, n - 1)(_detail::rng);
533 }
else if constexpr (std::is_floating_point_v<T>) {
534 tgen_ensure(n >= 0,
"value for `next` bust be valid");
535 return std::uniform_real_distribution<T>(0, n)(_detail::rng);
537 throw _detail::error(
"invalid type for next (" +
538 std::string(
typeid(T).name()) +
")");
543template <
typename T> T
next(T l, T r) {
544 _detail::ensure_registered();
545 tgen_ensure(l <= r,
"range for `next` bust be valid");
546 if constexpr (std::is_integral_v<T>)
547 return std::uniform_int_distribution<T>(l, r)(_detail::rng);
548 else if constexpr (std::is_floating_point_v<T>)
549 return std::uniform_real_distribution<T>(l, r)(_detail::rng);
551 throw _detail::error(
"invalid type for next (" +
552 std::string(
typeid(T).name()) +
")");
558 tgen_ensure(distribution.size() > 0,
"distribution must be non-empty");
561 std::accumulate(distribution.begin(), distribution.end(), T(0)));
562 for (size_t i = 0; i < distribution.size(); ++i) {
563 if (r < distribution[i])
565 r -= distribution[i];
567 return distribution.size() - 1;
570size_t next_by_distribution(
const std::initializer_list<T> &distribution) {
571 return next_by_distribution(std::vector<T>(distribution));
576template <
typename It>
void shuffle(It first, It last) {
580 for (It i = first + 1; i != last; ++i)
581 std::iter_swap(i, first + next(0,
static_cast<
int>(i - first)));
586template <
typename Inst, std::enable_if_t<is_sequential<Inst>::value,
int> = 0>
588 for (
int i = 0; i < inst.size(); ++i)
589 std::swap(inst[i], inst[next(0, inst.size() - 1)]);
594template <
typename C, std::enable_if_t<!is_associative_container<C>::value
and
595 !is_generator_instance<C>::value,
598 auto new_container = container;
599 shuffle(new_container.begin(), new_container.end());
600 return new_container;
603 std::enable_if_t<is_associative_container<C>::value,
int> = 0>
604[[nodiscard]] std::vector<
typename C::value_type> shuffled(
const C &container) {
605 return shuffled(std::vector<
typename C::value_type>(container.begin(),
609[[nodiscard]] std::vector<T> shuffled(
const std::initializer_list<T> &il) {
610 return shuffled(std::vector<T>(il));
615template <
typename Inst, std::enable_if_t<is_sequential<Inst>::value,
int> = 0>
617 Inst new_inst = inst;
625 int size = std::distance(first, last);
627 std::advance(it, next(0, size - 1));
634 std::enable_if_t<!is_generator_instance<C>::value,
int> = 0>
636 return any(container.begin(), container.end());
638template <
typename T> T any(
const std::initializer_list<T> &il) {
639 return any(std::vector<T>(il));
644template <
typename Inst, std::enable_if_t<is_sequential<Inst>::value,
int> = 0>
646 return inst[next<
int>(0, inst.size() - 1)];
651template <
typename C,
typename T,
652 std::enable_if_t<!is_generator_instance<C>::value,
int> = 0>
654 std::vector<T> distribution) {
655 tgen_ensure(container.size() == distribution.size(),
656 "container and distribution must have the same size");
657 auto it = container.begin();
658 std::advance(it, next_by_distribution(distribution));
661template <
typename C,
typename T,
662 std::enable_if_t<!is_generator_instance<C>::value,
int> = 0>
663typename C::value_type
664any_by_distribution(
const C &container,
665 const std::initializer_list<T> &distribution) {
666 return any_by_distribution(container, std::vector<T>(distribution));
668template <
typename T,
typename U>
669T any_by_distribution(
const std::initializer_list<T> &il,
670 const std::vector<U> &distribution) {
671 return any_by_distribution(std::vector<T>(il), distribution);
673template <
typename T,
typename U>
674T any_by_distribution(
const std::initializer_list<T> &il,
675 const std::initializer_list<U> &distribution) {
676 return any_by_distribution(std::vector<T>(il),
677 std::vector<U>(distribution));
682template <
typename Inst,
typename T,
683 std::enable_if_t<is_sequential<Inst>::value,
int> = 0>
687 "inst and distribution must have the same size");
688 return inst[next_by_distribution(distribution)];
690template <
typename Inst,
typename T,
691 std::enable_if_t<is_sequential<Inst>::value,
int> = 0>
692typename Inst::value_type
693any_by_distribution(
const Inst &inst,
694 const std::initializer_list<T> &distribution) {
695 return any_by_distribution(inst, std::vector<T>(distribution));
701 std::enable_if_t<!is_generator_instance<C>::value,
int> = 0>
703 tgen_ensure(0 < k
and k <=
static_cast<
int>(container.size()),
704 "number of elements to choose must be valid");
705 std::vector<
typename C::value_type> new_vec;
707 int need = k, left = container.size();
708 for (
auto cur_it = container.begin(); cur_it != container.end(); ++cur_it) {
709 if (next(1, left--) <= need) {
710 new_container.insert(new_container.end(), *cur_it);
714 return new_container;
717std::vector<T> choose(
int k,
const std::initializer_list<T> &il) {
718 return choose(k, std::vector<T>(il));
724template <
typename Inst, std::enable_if_t<is_sequential<Inst>::value
and
725 has_subset_defined<Inst>::value,
728 tgen_ensure(0 < k
and k <=
static_cast<
int>(inst.size()),
729 "number of elements to choose must be valid");
730 std::vector<
typename Inst::value_type> new_vec;
732 for (
int i = 0; need > 0; ++i) {
733 int left = inst.size() - i;
734 if (next(1, left) <= need) {
735 new_vec.push_back(inst[i]);
739 return Inst(new_vec);
746 std::map<T, T> virtual_list_;
752 T
size()
const {
return num_available_; }
760 T i = next<T>(0,
size() - 1);
763 T vi = virtual_list_.count(i) ? virtual_list_[i] : i;
764 T vj = virtual_list_.count(j) ? virtual_list_[j] : j;
765 virtual_list_[i] = vj;
776 for (
int i = 0; i < size; ++i)
777 res.push_back(
gen());
778 return typename sequence<T>::instance(res);
786 res.push_back(
gen());
787 return typename sequence<T>::instance(res);
793 std::vector<T> list_;
794 unique_range<size_t> idx_;
797 template <
typename C>
801 unique_container(
const std::initializer_list<T> &il)
802 : unique_container(std::vector<T>(il)) {}
809 T
gen() {
return list_[idx_.gen()]; }
815 for (
int i = 0; i < size; ++i)
816 res.push_back(
gen());
817 return typename sequence<T>::instance(res);
825 res.push_back(
gen());
826 return typename sequence<T>::instance(res);
833
834
835
836
839
840
841
842
843
844
845
846
847
848
849
850
851
854
855
859 _detail::cpp = _detail::cpp_value(version);
863
864
867inline _detail::compiler_value gcc(
int major = 0,
int minor = 0) {
868 return {_detail::compiler_kind::gcc, major, minor};
872inline _detail::compiler_value clang(
int major = 0,
int minor = 0) {
873 return {_detail::compiler_kind::clang, major, minor};
878 _detail::compiler.kind_ = compiler.kind_;
879 _detail::compiler.major_ = compiler.major_;
880 _detail::compiler.minor_ = compiler.minor_;
887inline bool process_special_opt_flags(std::string &key) {
889 if (key.find(
"tgen::CPP:") == 0) {
890 int prefix_len = std::string(
"tgen::CPP:").size();
891 tgen_ensure(
static_cast<
int>(key.size()) == prefix_len + 2
and
892 std::isdigit(key[prefix_len])
and
893 std::isdigit(key[prefix_len + 1]),
894 "invalid CPP format");
895 int version = std::stoi(key.substr(prefix_len, 2));
902 _detail::compiler_kind kind;
903 size_t prefix_len = 0;
905 if (key.find(
"tgen::GCC") == 0) {
906 kind = _detail::compiler_kind::gcc;
907 prefix_len = std::string(
"tgen::GCC").size();
908 }
else if (key.find(
"tgen::CLANG") == 0) {
909 kind = _detail::compiler_kind::clang;
910 prefix_len = std::string(
"tgen::CLANG").size();
915 if (key.size() == prefix_len) {
920 tgen_ensure(key[prefix_len] ==
':',
"invalid compiler format");
923 std::string inside = key.substr(prefix_len, key.size() - prefix_len);
924 int major = 0, minor = 0;
926 size_t dot = inside.find(
'.');
927 if (dot == std::string::npos) {
929 std::all_of(inside.begin(), inside.end(), ::isdigit),
930 "invalid compiler version");
931 major = std::stoi(inside);
933 std::string maj = inside.substr(0, dot);
934 std::string min = inside.substr(dot + 1);
937 std::all_of(maj.begin(), maj.end(), ::isdigit)
and
939 "invalid compiler major version");
941 std::all_of(min.begin(), min.end(), ::isdigit)
and
943 "invalid compiler minor version");
945 major = std::stoi(maj);
946 minor = std::stoi(min);
954inline std::vector<std::string>
956inline std::map<std::string, std::string>
959template <
typename T> T get_opt(
const std::string &value) {
961 if constexpr (std::is_same_v<T,
bool>) {
962 if (value ==
"true" or value ==
"1")
964 if (value ==
"false" or value ==
"0")
966 }
else if constexpr (std::is_integral_v<T>) {
967 if constexpr (std::is_unsigned_v<T>)
968 return static_cast<T>(std::stoull(value));
970 return static_cast<T>(std::stoll(value));
971 }
else if constexpr (std::is_floating_point_v<T>)
972 return static_cast<T>(std::stold(value));
978 throw _detail::error(
"invalid value `" + value +
"` for type " +
982inline void parse_opts(
int argc,
char **argv) {
985 for (
int i = 1; i < argc; ++i) {
986 std::string key(argv[i]);
988 if (process_special_opt_flags(key))
993 "invalid opt (" + std::string(argv[i]) +
")");
994 if (
'0' <= key[1]
and key[1] <=
'9') {
996 _detail::pos_opts.push_back(key);
1001 key = key.substr(1);
1004 _detail::pos_opts.push_back(key);
1009 if (key[0] ==
'-') {
1011 "invalid opt (" + std::string(argv[i]) +
")");
1014 key = key.substr(1);
1021 std::size_t eq = key.find(
'=');
1022 if (eq != std::string::npos) {
1024 std::string value = key.substr(eq + 1);
1025 key = key.substr(0, eq);
1027 "expected non-empty key/value in opt (" +
1028 std::string(argv[1]));
1030 "cannot have repeated keys");
1031 _detail::named_opts[key] = value;
1035 "cannot have repeated keys");
1036 tgen_ensure(argv[i + 1],
"value cannot be empty");
1037 _detail::named_opts[key] = std::string(argv[i + 1]);
1043inline void set_seed(
int argc,
char **argv) {
1044 std::vector<uint32_t> seed;
1047 for (
int i = 1; i < argc; ++i) {
1049 int size_pos = seed.size();
1051 for (
char *s = argv[i]; *s !=
'\0'; ++s) {
1056 std::seed_seq seq(seed.begin(), seed.end());
1057 _detail::rng.seed(seq);
1064 tgen::_detail::ensure_registered();
1065 return 0 <= index
and index < _detail::pos_opts.size();
1070 tgen::_detail::ensure_registered();
1071 return _detail::named_opts.count(key) != 0;
1076template <
typename T>
1077T
opt(size_t index, std::optional<T> default_value = std::nullopt) {
1078 tgen::_detail::ensure_registered();
1079 if (!has_opt(index)) {
1081 return *default_value;
1082 throw _detail::error(
"cannot find key with index " +
1083 std::to_string(index));
1085 return _detail::get_opt<T>(_detail::pos_opts[index]);
1090template <
typename T>
1091T
opt(
const std::string &key, std::optional<T> default_value = std::nullopt) {
1092 tgen::_detail::ensure_registered();
1095 return *default_value;
1096 throw _detail::error(
"cannot find key with key " + key);
1098 return _detail::get_opt<T>(_detail::named_opts[key]);
1103 _detail::set_seed(argc, argv);
1105 _detail::pos_opts.clear();
1106 _detail::named_opts.clear();
1107 _detail::parse_opts(argc, argv);
1109 _detail::registered =
true;
1115 _detail::rng.seed(*seed);
1117 _detail::rng.seed();
1119 _detail::pos_opts.clear();
1120 _detail::named_opts.clear();
1122 _detail::registered =
true;
1126
1127
1128
1129
1132
1133
1137 T value_l_, value_r_;
1138 std::set<T> values_;
1143 std::vector<std::pair<T, T>> val_range_;
1144 std::vector<std::vector<
int>> neigh_;
1145 std::vector<std::set<
int>>
1146 distinct_restrictions_;
1150 : size_(size), value_l_(value_l), value_r_(value_r),
neigh_(
size) {
1151 tgen_ensure(size_ > 0,
"sequence: size must be positive");
1153 "sequence: value range must be valid");
1154 for (
int i = 0; i < size_; ++i)
1155 val_range_.emplace_back(value_l_, value_r_);
1161 tgen_ensure(size_ > 0,
"sequence: size must be positive");
1162 tgen_ensure(!values.empty(),
"sequence: value set must be non-empty");
1163 value_l_ = 0, value_r_ = values.size() - 1;
1164 for (
int i = 0; i < size_; ++i)
1165 val_range_.emplace_back(value_l_, value_r_);
1167 for (T value : values_)
1168 value_idx_in_set_[value] = idx++;
1173 tgen_ensure(0 <= idx
and idx < size_,
"sequence: index must be valid");
1174 if (values_.size() == 0) {
1175 auto &[left, right] = val_range_[idx];
1176 if (left == right
and value_l_ != value_r_) {
1178 "sequence: must not set to two different values");
1181 "sequence: value must be in the defined range");
1183 left = right = value;
1186 "sequence: value must be in the set of values");
1187 auto &[left, right] = val_range_[idx];
1188 int new_val = value_idx_in_set_[value];
1190 "sequence: must not set to two different values");
1191 left = right = new_val;
1199 std::max(idx_1, idx_2) < size_,
1200 "sequence: indices must be valid");
1204 neigh_[idx_1].push_back(idx_2);
1205 neigh_[idx_2].push_back(idx_1);
1211 tgen_ensure(0 <= left
and left <= right
and right < size_,
1212 "sequence: range indices bust be valid");
1213 for (
int i = left; i < right; ++i)
1222 if (!indices.empty())
1223 distinct_restrictions_.push_back(indices);
1229 std::set<
int> indices = {idx_1, idx_2};
1235 std::vector<
int> indices(size_);
1236 std::iota(indices.begin(), indices.end(), 0);
1237 return distinct(std::set<
int>(indices.begin(), indices.end()));
1243 using tgen_is_sequential_tag = _detail::is_sequential_tag;
1244 using tgen_has_subset_defined_tag = _detail::has_subset_defined_tag;
1246 using value_type = T;
1248 std::vector<T> vec_;
1252 instance(
const std::initializer_list<T> &il)
1253 : instance(std::vector<T>(il)) {}
1256 int size()
const {
return vec_.size(); }
1261 "sequence: instance: index out of bounds");
1264 const T &operator[](
int idx)
const {
1266 "sequence: instance: index out of bounds");
1273 std::sort(vec_.begin(), vec_.end());
1280 std::reverse(vec_.begin(), vec_.end());
1294 std::vector<T> new_vec = vec_;
1295 for (
int i = 0; i < rhs
.size(); ++i)
1296 new_vec.push_back(rhs[i]);
1301 friend std::ostream &operator<<(std::ostream &out,
1303 for (
int i = 0; i < inst.size(); ++i) {
1318 generate_distinct_values(
int k,
const std::set<T> &forbidden_values)
const {
1319 for (
auto forbidden : forbidden_values)
1320 tgen_ensure(value_l_ <= forbidden
and forbidden <= value_r_);
1325 T num_available = (value_r_ - value_l_ + 1) - forbidden_values.size();
1326 if (num_available < k)
1327 throw _detail::complex_restrictions_error(
1328 "sequence",
"not enough distinct values");
1329 std::map<T, T> virtual_list;
1330 std::vector<T> gen_list;
1331 for (
int i = 0; i < k; ++i) {
1332 T j = next<T>(i, num_available - 1);
1333 T vj = virtual_list.count(j) ? virtual_list[j] : j;
1334 T vi = virtual_list.count(i) ? virtual_list[i] : i;
1336 virtual_list[j] = vi, virtual_list[i] = vj;
1338 gen_list.push_back(virtual_list[i]);
1343 for (T &value : gen_list)
1348 std::vector<std::pair<T,
int>> values_sorted;
1349 for (std::size_t i = 0; i < gen_list.size(); ++i)
1350 values_sorted.emplace_back(gen_list[i], i);
1352 std::sort(values_sorted.begin(), values_sorted.end());
1353 auto cur_it = forbidden_values.begin();
1354 int smaller_forbidden_count = 0;
1355 for (
auto [val, idx] : values_sorted) {
1356 while (cur_it != forbidden_values.end()
and
1357 *cur_it <= val + smaller_forbidden_count)
1358 ++cur_it, ++smaller_forbidden_count;
1359 gen_list[idx] += smaller_forbidden_count;
1368 std::vector<T> vec(size_);
1369 std::vector<
bool> defined_idx(
1372 std::vector<
int> comp_id(size_, -1);
1373 std::vector<std::vector<
int>> comp(size_);
1377 auto define_comp = [&](
int cur_comp, T val) {
1378 for (
int idx : comp[cur_comp]) {
1381 defined_idx[idx] =
true;
1387 std::vector<
bool> vis(size_,
false);
1388 for (
int idx = 0; idx < size_; ++idx)
1391 bool value_defined =
false;
1395 std::queue<
int> q({idx});
1397 std::vector<
int> component;
1398 while (!q.empty()) {
1399 int cur_idx = q.front();
1402 component.push_back(cur_idx);
1405 auto [l, r] = val_range_[cur_idx];
1407 if (!value_defined) {
1409 value_defined =
true;
1411 }
else if (new_value != l) {
1413 throw _detail::contradiction_error(
1415 "tried to set value to `" +
1416 std::to_string(new_value) +
1417 "`, but it was already set as `" +
1418 std::to_string(l) +
"`");
1422 for (
int nxt_idx : neigh_[cur_idx]) {
1423 if (!vis[nxt_idx]) {
1424 vis[nxt_idx] =
true;
1431 for (
int cur_idx : component) {
1432 comp_id[cur_idx] = comp_count;
1433 comp[comp_id[cur_idx]].push_back(cur_idx);
1438 define_comp(comp_count, new_value);
1445 std::vector<std::set<
int>> distinct_containing_comp_idx(comp_count);
1448 for (
const std::set<
int> &distinct : distinct_restrictions_) {
1450 if (
static_cast<uint64_t>(distinct.size() - 1) +
1451 static_cast<uint64_t>(value_l_) >
1452 static_cast<uint64_t>(value_r_))
1453 throw _detail::contradiction_error(
1455 "tried to generate " + std::to_string(distinct.size()) +
1456 " distinct values, but the maximum is " +
1457 std::to_string(value_r_ - value_l_ + 1));
1461 std::set<
int> comp_ids;
1462 for (
int idx : distinct) {
1463 if (comp_ids.count(comp_id[idx]))
1464 throw _detail::contradiction_error(
1465 "sequence",
"tried to set two indices as equal and "
1467 comp_ids.insert(comp_id[idx]);
1469 distinct_containing_comp_idx[comp_id[idx]].insert(dist_id);
1476 for (
auto &distinct_containing : distinct_containing_comp_idx)
1477 if (distinct_containing.size() >= 3)
1478 throw _detail::complex_restrictions_error(
1480 "one index can not be in >= 3 distinct restrictions");
1482 std::vector<
bool> vis_distinct(distinct_restrictions_.size(),
false);
1483 std::vector<
bool> initially_defined_comp_idx(comp_count,
false);
1486 auto define_tree = [&](
int distinct_id) {
1491 std::set<T> defined_values;
1492 for (
int idx : distinct_restrictions_[distinct_id])
1493 if (defined_idx[idx]) {
1496 if (defined_values.count(vec[idx]))
1497 throw _detail::contradiction_error(
1499 "tried to set two indices as equal and different");
1501 defined_values.insert(vec[idx]);
1506 int new_value_count =
1507 distinct_restrictions_[distinct_id].size() -
1508 static_cast<
int>(defined_values.size());
1509 std::vector<T> generated_values =
1510 generate_distinct_values(new_value_count, defined_values);
1511 auto val_it = generated_values.begin();
1512 for (
int idx : distinct_restrictions_[distinct_id])
1513 if (defined_idx[idx]) {
1516 initially_defined_comp_idx[comp_id[idx]] =
false;
1518 define_comp(comp_id[idx], *val_it);
1524 std::queue<std::pair<
int,
int>> q;
1525 q.emplace(distinct_id, -1);
1526 vis_distinct[distinct_id] =
true;
1527 while (!q.empty()) {
1528 auto [cur_distinct, parent] = q.front();
1531 std::set<
int> neigh_distinct;
1532 for (
int idx : distinct_restrictions_[cur_distinct])
1533 for (
int nxt_distinct :
1534 distinct_containing_comp_idx[comp_id[idx]]) {
1535 if (nxt_distinct == cur_distinct
or
1536 nxt_distinct == parent)
1540 if (vis_distinct[nxt_distinct])
1541 throw _detail::complex_restrictions_error(
1543 "cycle found in distinct restrictions");
1545 neigh_distinct.insert(nxt_distinct);
1548 for (
int nxt_distinct : neigh_distinct) {
1549 vis_distinct[nxt_distinct] =
true;
1550 q.emplace(nxt_distinct, cur_distinct);
1553 std::set<T> nxt_defined_values;
1554 for (
int idx2 : distinct_restrictions_[nxt_distinct])
1555 if (defined_idx[idx2]) {
1559 if (initially_defined_comp_idx[comp_id[idx2]])
1560 throw _detail::complex_restrictions_error(
1563 nxt_defined_values.insert(vec[idx2]);
1565 int new_value_count =
1566 distinct_restrictions_[nxt_distinct].size() -
1567 static_cast<
int>(nxt_defined_values.size());
1568 std::vector<T> generated_values = generate_distinct_values(
1569 new_value_count, nxt_defined_values);
1570 auto val_it = generated_values.begin();
1571 for (
int idx2 : distinct_restrictions_[nxt_distinct])
1572 if (!defined_idx[idx2]) {
1573 define_comp(comp_id[idx2], *val_it);
1585 std::vector<std::pair<
int,
int>> defined_cnt_and_distinct_idx;
1587 for (
const std::set<
int> &distinct : distinct_restrictions_) {
1588 int defined_cnt = 0;
1589 for (
int idx : distinct)
1590 if (defined_idx[idx]) {
1592 initially_defined_comp_idx[comp_id[idx]] =
true;
1594 defined_cnt_and_distinct_idx.emplace_back(defined_cnt, dist_id);
1598 std::sort(defined_cnt_and_distinct_idx.rbegin(),
1599 defined_cnt_and_distinct_idx.rend());
1600 for (
auto [defined_cnt, distinct_idx] :
1601 defined_cnt_and_distinct_idx)
1602 if (!vis_distinct[distinct_idx])
1603 define_tree(distinct_idx);
1607 for (std::size_t dist_id = 0; dist_id < distinct_restrictions_.size();
1609 if (!vis_distinct[dist_id])
1610 define_tree(dist_id);
1615 for (
int idx = 0; idx < size_; ++idx)
1616 if (!defined_idx[idx])
1617 define_comp(comp_id[idx], next<T>(value_l_, value_r_));
1619 if (!values_.empty()) {
1621 std::vector<T> value_vec(values_.begin(), values_.end());
1623 val = value_vec[val];
1631
1632
1633
1634
1637
1638
1639
1640
1644 std::vector<std::pair<
int,
int>> defs_;
1645 std::optional<std::vector<
int>> cycle_sizes_;
1649 tgen_ensure(size_ > 0,
"permutation: size must be positive");
1655 "permutation: index must be valid");
1656 defs_.emplace_back(idx, value);
1663 size_ == std::accumulate(cycle_sizes.begin(), cycle_sizes.end(), 0),
1664 "permutation: cycle sizes must add up to size of permutation");
1665 cycle_sizes_ = cycle_sizes;
1668 permutation &cycles(
const std::initializer_list<
int> &cycle_sizes) {
1669 return cycles(std::vector<
int>(cycle_sizes));
1675 using tgen_is_sequential_tag = _detail::is_sequential_tag;
1678 std::vector<
int> vec_;
1683 :
vec_(
vec), sep_(
' '), add_1_(
false) {
1685 "permutation: instance: cannot be empty");
1686 std::vector<
bool> vis(vec_.size(),
false);
1687 for (
int i = 0; i <
size(); ++i) {
1689 vec_[i] <
static_cast<
int>(vec_.size()),
1690 "permutation: instance: values must be from `0` to "
1694 "permutation: instance: cannot have repeated values");
1695 vis[vec_[i]] =
true;
1698 instance(
const std::initializer_list<
int> &il)
1699 : instance(std::vector<
int>(il)) {}
1702 int size()
const {
return vec_.size(); }
1707 "permutation: instance: index out of bounds");
1714 std::vector<
bool> vis(
size(),
false);
1717 for (
int i = 0; i <
size(); ++i)
1720 for (
int j = i; !vis[j]; j = vec_[j])
1724 return ((
size() - cycles) % 2 == 0) ? +1 : -1;
1730 for (
int i = 0; i < size(); ++i)
1738 std::reverse(vec_.begin(), vec_.end());
1745 std::vector<
int> inv(
size());
1746 for (
int i = 0; i < size(); ++i)
1767 friend std::ostream &operator<<(std::ostream &out,
1769 for (
int i = 0; i < inst
.size(); ++i) {
1772 out << inst
[i
] + inst.add_1_;
1784 if (!cycle_sizes_) {
1786 std::vector<
int> idx_to_val(size_, -1), val_to_idx(size_, -1);
1787 for (
auto [idx, val] : defs_) {
1789 0 <= val
and val < size_,
1790 "permutation: value in permutation must be in [0, " +
1791 std::to_string(size_) +
")");
1793 if (idx_to_val[idx] != -1) {
1795 "permutation: cannot set an idex to two "
1796 "different values");
1798 idx_to_val[idx] = val;
1800 if (val_to_idx[val] != -1) {
1802 "permutation: cannot set two indices to the "
1805 val_to_idx[val] = idx;
1808 std::vector<
int> perm(size_);
1809 std::iota(perm.begin(), perm.end(), 0);
1810 shuffle(perm.begin(), perm.end());
1812 for (
int &i : idx_to_val)
1815 while (val_to_idx[perm[cur_idx]] != -1)
1817 i = perm[cur_idx++];
1823 std::vector<
int> order(size_);
1824 std::iota(order.begin(), order.end(), 0);
1825 shuffle(order.begin(), order.end());
1827 std::vector<std::vector<
int>> cycles;
1828 for (
int cycle_size : *cycle_sizes_) {
1829 cycles.emplace_back();
1830 for (
int i = 0; i < cycle_size; ++i)
1831 cycles.back().push_back(order[idx++]);
1835 std::vector<
int> perm(size_, -1);
1836 for (
const std::vector<
int> &cycle : cycles) {
1837 int cur_size = cycle.size();
1838 for (
int i = 0; i < cur_size; ++i)
1839 perm[cycle[i]] = cycle[(i + 1) % cur_size];
1847
1848
1849
1850
1856inline int popcount(uint64_t x) {
return __builtin_popcountll(x); }
1858inline int ctzll(uint64_t x) {
1861 static const unsigned char index64[64] = {
1862 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
1863 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
1864 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
1865 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12};
1866 return index64[((x & -x) * 0x022FDD63CC95386D) >> 58];
1869inline uint64_t mul_mod(uint64_t a, uint64_t b, uint64_t m) {
1870 return static_cast<
unsigned __int128>(a) * b % m;
1875inline uint64_t expo_mod(uint64_t x, uint64_t y, uint64_t m) {
1878 uint64_t ans = expo_mod(mul_mod(x, x, m), y / 2, m);
1879 return y % 2 ? mul_mod(x, ans, m) : ans;
1888 if (n == 2
or n == 3)
1893 uint64_t r = _detail::ctzll(n - 1), d = n >> r;
1895 for (
int a : {2, 325, 9375, 28178, 450775, 9780504, 1795265022}) {
1896 uint64_t x = _detail::expo_mod(a, d, n);
1897 if (x == 1
or x == n - 1
or a % n == 0)
1900 for (uint64_t j = 0; j < r - 1; ++j) {
1901 x = _detail::mul_mod(x, x, n);
1913inline uint64_t pollard_rho(uint64_t n) {
1916 auto f = [n](uint64_t x) {
return mul_mod(x, x, n) + 1; };
1918 uint64_t x = 0, y = 0, t = 30, prd = 2, x0 = 1, q;
1919 while (t % 40 != 0
or std::gcd(prd, n) == 1) {
1922 q = mul_mod(prd, x > y ? x - y : y - x, n);
1925 x = f(x), y = f(f(y)), t++;
1927 return std::gcd(prd, n);
1930inline std::vector<uint64_t> factor(uint64_t n) {
1935 uint64_t d = _detail::pollard_rho(n);
1936 std::vector<uint64_t> l = factor(d), r = factor(n / d);
1937 l.insert(l.end(), r.begin(), r.end());
1942template <
typename T>
1943std::runtime_error there_is_no_in_range_error(
const std::string &type, T l,
1945 return tgen::_detail::error(
"math: there is no " + type +
" in range [" +
1946 std::to_string(l) +
", " + std::to_string(r) +
1949template <
typename T>
1950std::runtime_error there_is_no_from_error(
const std::string &type, T r) {
1951 return tgen::_detail::error(
"math: there is no " + type +
" from " +
1954template <
typename T>
1955std::runtime_error there_is_no_upto_error(
const std::string &type, T r) {
1956 return tgen::_detail::error(
"math: there is no " + type +
" up to " +
1963inline __int128 modular_inverse_128(
__int128 a,
__int128 mod) {
1965 "math: remainder must be positive and smaller than the mod");
1967 __int128 t = 0, new_t = 1;
1968 __int128 r = mod, new_r = a;
1970 while (new_r != 0) {
1971 __int128 q = r / new_r;
1973 auto tmp_t = t - q * new_t;
1977 auto tmp_r = r - q * new_r;
1982 tgen_ensure(r == 1,
"math: remainder and mod must be coprime");
1990inline bool mul_leq(uint64_t a, uint64_t b, uint64_t limit) {
1993 return a <= limit / b;
1997inline std::optional<uint64_t> expo(uint64_t base, uint64_t exp,
1999 uint64_t result = 1;
2003 if (!mul_leq(result, base, limit))
2004 return std::nullopt;
2013 if (!mul_leq(base, base, limit))
2014 return std::nullopt;
2023inline uint64_t kth_root_floor(uint64_t n, uint64_t k) {
2024 tgen::_detail::tgen_ensure_against_bug(k > 0
and n >= 0,
2025 "math: values must be valid");
2026 if (k == 1
or n <= 1)
2029 uint64_t lo = 1, hi = 1ULL << ((64 + k - 1) / k);
2032 uint64_t mid = lo + (hi - lo + 1) / 2;
2034 if (expo(mid, k, n)) {
2045inline __int128 gcd128(
__int128 a,
__int128 b) {
2061inline __int128 mul_saturate(
__int128 a,
__int128 b) {
2063 static const __int128 LIMIT = (
__int128)1 << 64;
2064 if (a == 0
or b == 0)
2075 crt() : a(0), m(1) {}
2076 crt(T a_, T m_) : a(a_), m(m_) {}
2077 crt operator*(crt C) {
2078 if (m == 0
or C.m == 0)
2081 T g = gcd128(m, C.m);
2082 if ((C.a - a) % g != 0)
2091 T inv = modular_inverse_128(m1 % m2, m2);
2093 T k = ((C.a - a) / g) % m2;
2097 k =
static_cast<
unsigned __int128>(k) * inv % m2;
2099 T lcm = mul_saturate(m, m2);
2101 T res = (a +
static_cast<T>((
static_cast<
unsigned __int128>(k) * m) %
2113inline constexpr long double LOG_ZERO = -INFINITY;
2114inline constexpr long double LOG_ONE = 0.0;
2116inline long double log_space(
long double x) {
2117 return x == 0.0 ? LOG_ZERO : std::log(x);
2121inline long double add_log_space(
long double a,
long double b) {
2130 return a + log1p(exp(b - a));
2135inline long double sub_log_space(
long double a,
long double b) {
2140 return a + log1p(-exp(b - a));
2149 tgen_ensure(n > 0,
"math: number to factor must be positive");
2150 auto factors = _detail::factor(n);
2151 std::sort(factors.begin(), factors.end());
2159 tgen_ensure(n > 0,
"math: number to factor must be positive");
2160 std::vector<std::pair<uint64_t,
int>> primes;
2161 for (uint64_t p : factor(n)) {
2162 if (!primes.empty()
and primes.back().first == p)
2163 ++primes.back().second;
2165 primes.emplace_back(p, 1);
2174 return _detail::modular_inverse_128(a, mod);
2180 tgen_ensure(n > 0,
"math: totient(0) is undefined");
2183 for (
auto [p, e] : factor_by_prime(n))
2190inline const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> &
2193 static const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> value{
2195 2, 3, 7, 23, 89, 113, 523, 887, 1129, 1327, 9551, 15683, 19609,
2196 31397, 155921, 360653, 370261, 492113, 1349533, 1357201, 2010733,
2197 4652353, 17051707, 20831323, 47326693, 122164747, 189695659,
2198 191912783, 387096133, 436273009, 1294268491, 1453168141,
2199 2300942549, 3842610773, 4302407359, 10726904659, 20678048297,
2200 22367084959, 25056082087, 42652618343, 127976334671, 182226896239,
2201 241160624143, 297501075799, 303371455241, 304599508537,
2202 416608695821, 461690510011, 614487453523, 738832927927,
2203 1346294310749, 1408695493609, 1968188556461, 2614941710599,
2204 7177162611713, 13829048559701, 19581334192423, 42842283925351,
2205 90874329411493, 171231342420521, 218209405436543, 1189459969825483,
2206 1686994940955803, 1693182318746371, 43841547845541059,
2207 55350776431903243, 80873624627234849, 203986478517455989,
2208 218034721194214273, 305405826521087869, 352521223451364323,
2209 401429925999153707, 418032645936712127, 804212830686677669,
2210 1425172824437699411, 5733241593241196731, 6787988999657777797
2212 {1, 2, 4, 6, 8, 14, 18, 20, 22, 34, 36,
2213 44, 52, 72, 86, 96, 112, 114, 118, 132, 148, 154,
2214 180, 210, 220, 222, 234, 248, 250, 282, 288, 292, 320,
2215 336, 354, 382, 384, 394, 456, 464, 468, 474, 486, 490,
2216 500, 514, 516, 532, 534, 540, 582, 588, 602, 652, 674,
2217 716, 766, 778, 804, 806, 906, 916, 924, 1132, 1184, 1198,
2218 1220, 1224, 1248, 1272, 1328, 1356, 1370, 1442, 1476, 1488, 1510}};
2227 throw _detail::there_is_no_upto_error(
"prime gap", r);
2229 const auto &[P, G] = prime_gaps();
2230 for (
int i = P.size() - 1;; --i) {
2234 uint64_t right = std::min(r, P[i] + G[i] - 1);
2235 uint64_t prev = i > 0 ? G[i - 1] : 0;
2236 uint64_t curr = right - P[i];
2239 return {P[i] + 1, right};
2246 static const std::vector<uint64_t> highly_composites = {
2247 1, 2, 4, 6, 12, 24, 36, 48, 60, 120, 180, 240, 360, 720, 840, 1260, 1680,
2248 2520, 5040, 7560, 10080, 15120, 20160, 25200, 27720, 45360, 50400, 55440,
2249 83160, 110880, 166320, 221760, 277200, 332640, 498960, 554400, 665280,
2250 720720, 1081080, 1441440, 2162160, 2882880, 3603600, 4324320, 6486480,
2251 7207200, 8648640, 10810800, 14414400, 17297280, 21621600, 32432400,
2252 36756720, 43243200, 61261200, 73513440, 110270160, 122522400, 147026880,
2253 183783600, 245044800, 294053760, 367567200, 551350800, 698377680, 735134400,
2254 1102701600, 1396755360, 2095133040, 2205403200, 2327925600, 2793510720,
2255 3491888400, 4655851200, 5587021440, 6983776800, 10475665200, 13967553600,
2256 20951330400, 27935107200, 41902660800, 48886437600, 64250746560,
2257 73329656400, 80313433200, 97772875200, 128501493120, 146659312800,
2258 160626866400, 240940299600, 293318625600, 321253732800, 481880599200,
2259 642507465600, 963761198400, 1124388064800, 1606268664000, 1686582097200,
2260 1927522396800, 2248776129600, 3212537328000, 3373164194400, 4497552259200,
2261 6746328388800, 8995104518400, 9316358251200, 13492656777600, 18632716502400,
2262 26985313555200, 27949074753600, 32607253879200, 46581791256000,
2263 48910880818800, 55898149507200, 65214507758400, 93163582512000,
2264 97821761637600, 130429015516800, 195643523275200, 260858031033600,
2265 288807105787200, 391287046550400, 577614211574400, 782574093100800,
2266 866421317361600, 1010824870255200, 1444035528936000, 1516237305382800,
2267 1732842634723200, 2021649740510400, 2888071057872000, 3032474610765600,
2268 4043299481020800, 6064949221531200, 8086598962041600, 10108248702552000,
2269 12129898443062400, 18194847664593600, 20216497405104000, 24259796886124800,
2270 30324746107656000, 36389695329187200, 48519593772249600, 60649492215312000,
2271 72779390658374400, 74801040398884800, 106858629141264000,
2272 112201560598327200, 149602080797769600, 224403121196654400,
2273 299204161595539200, 374005201994424000, 448806242393308800,
2274 673209363589963200, 748010403988848000, 897612484786617600,
2275 1122015605983272000, 1346418727179926400, 1795224969573235200,
2276 2244031211966544000, 2692837454359852800, 3066842656354276800,
2277 4381203794791824000, 4488062423933088000, 6133685312708553600,
2278 8976124847866176000, 9200527969062830400, 12267370625417107200ULL,
2279 15334213281771384000ULL, 18401055938125660800ULL};
2280 return highly_composites;
2285 for (
int i = highly_composites().size() - 1; i >= 0; --i)
2286 if (highly_composites()[i] <= r)
2287 return highly_composites()[i];
2289 throw _detail::there_is_no_upto_error(
"highly composite number", r);
2296 throw _detail::there_is_no_in_range_error(
"prime", l, r);
2297 l = std::max<uint64_t>(l, 2);
2298 auto [l_gap, r_gap] = prime_gap_upto(r);
2299 if (r - l + 1 <= r_gap - l_gap + 1) {
2301 std::vector<uint64_t> vals(r - l + 1);
2302 iota(vals.begin(), vals.end(), l);
2303 shuffle(vals.begin(), vals.end());
2304 for (uint64_t i : vals)
2307 throw _detail::there_is_no_in_range_error(
"prime", l, r);
2320 tgen_ensure(l <= std::numeric_limits<uint64_t>::max() - 58,
2321 "math: invalid bound");
2322 for (uint64_t i = std::max<uint64_t>(2, l);; ++i)
2330 for (uint64_t i = r; i >= 2; --i)
2333 throw _detail::there_is_no_upto_error(
"prime", r);
2340 for (
auto [p, e] : factor_by_prime(n))
2341 divisors *= (e + 1);
2349 "math: divisor count must be prime");
2350 int root = divisor_count - 1;
2351 uint64_t p =
gen_prime(_detail::kth_root_floor(l, root)
,
2352 _detail::kth_root_floor(r, root)
);
2353 return *_detail::expo(p, root, r);
2360 std::vector<uint64_t> rems,
2361 std::vector<uint64_t> mods) {
2363 throw _detail::there_is_no_in_range_error(
"congruent number", l, r);
2365 "math: number of remainders and mods must be the same");
2366 tgen_ensure(rems.size() > 0,
"math: must have at least one congruence");
2369 for (
int i = 0; i <
static_cast<
int>(rems.size()); ++i) {
2371 "math: remainder must be smaller than the mod");
2372 crt = crt * _detail::crt(rems[i], mods[i]);
2375 throw _detail::there_is_no_in_range_error(
"congruent number", l, r);
2377 if (!(l <= crt.a
and crt.a <= r))
2378 throw _detail::there_is_no_in_range_error(
"congruent number", l,
2381 for (
int j = 0; j <
static_cast<
int>(rems.size()); ++j)
2382 if (crt.a % mods[j] != rems[j])
2383 throw _detail::there_is_no_in_range_error(
2384 "congruent number", l, r);
2389 uint64_t k_min = crt.a >= l ? 0 : ((l - crt.a) + crt.m - 1) / crt.m;
2390 uint64_t k_max = (r - crt.a) / crt.m;
2393 throw _detail::there_is_no_in_range_error(
"congruent number", l, r);
2395 return crt.a + next(k_min, k_max) * crt.m;
2402 return gen_congruent(l, r, std::vector<uint64_t>({rem}),
2403 std::vector<uint64_t>({mod}));
2411 std::vector<uint64_t> mods) {
2413 "math: number of remainders and mods must be the same");
2414 tgen_ensure(rems.size() > 0,
"math: must have at least one congruence");
2417 for (
int i = 0; i <
static_cast<
int>(rems.size()); ++i) {
2419 "math: remainder must be smaller than the mod");
2420 crt = crt * _detail::crt(rems[i], mods[i]);
2423 throw _detail::there_is_no_from_error(
"congruent number", l);
2424 if (crt.m > std::numeric_limits<uint64_t>::max()) {
2426 throw tgen::_detail::error(
2427 "math: congruent number does not exist or is too large");
2429 for (
int j = 0; j <
static_cast<
int>(rems.size()); ++j)
2430 if (crt.a % mods[j] != rems[j])
2431 throw tgen::_detail::error(
"math: congruent number does "
2432 "not exist or is too large");
2439 k = ((l - crt.a) + crt.m - 1) / crt.m;
2440 __int128 result = crt.a + k * crt.m;
2442 if (result > std::numeric_limits<uint64_t>::max())
2443 throw tgen::_detail::error(
"math: congruent number is too large");
2444 return static_cast<uint64_t>(result);
2450 return congruent_from(l, std::vector<uint64_t>{rem},
2451 std::vector<uint64_t>{mod});
2459 std::vector<uint64_t> mods) {
2461 "math: number of remainders and mods must be the same");
2462 tgen_ensure(rems.size() > 0,
"math: must have at least one congruence");
2465 for (
int i = 0; i <
static_cast<
int>(rems.size()); ++i) {
2467 "math: remainder must be smaller than the mod");
2469 crt = crt * _detail::crt(rems[i], mods[i]);
2472 throw _detail::there_is_no_upto_error(
"congruent number", r);
2475 throw _detail::there_is_no_upto_error(
"congruent number", r);
2477 for (
int j = 0; j <
static_cast<
int>(rems.size()); ++j)
2478 if (crt.a % mods[j] != rems[j])
2479 throw _detail::there_is_no_upto_error(
"congruent number",
2486 throw _detail::there_is_no_upto_error(
"congruent number", r);
2488 uint64_t k = (r - crt.a) / crt.m;
2489 __int128 result = crt.a + k * crt.m;
2492 throw _detail::there_is_no_upto_error(
"congruent number", r);
2493 return static_cast<uint64_t>(result);
2499 return congruent_upto(r, std::vector<uint64_t>{rem},
2500 std::vector<uint64_t>{mod});
2508 static const std::vector<uint64_t> fib = [] {
2509 std::vector<uint64_t> v = {0, 1};
2511 std::numeric_limits<uint64_t>::max() - v[v.size() - 2])
2512 v.push_back(v.back() + v[v.size() - 2]);
2526 part_r = std::min(*part_r, n);
2528 "math: invalid parameters to gen_partition");
2529 tgen_ensure(part_l <= n
and *part_r > 0,
"math: no such partition");
2532 std::vector<
long double> dp(n + 1, _detail::LOG_ZERO);
2533 dp[0] = _detail::LOG_ONE;
2534 long double window = _detail::LOG_ZERO;
2535 for (
int i = 1; i <= n; ++i) {
2537 window = _detail::add_log_space(window, dp[i - part_l]);
2538 if (i >= *part_r + 1)
2539 window = _detail::sub_log_space(window, dp[i - *part_r - 1]);
2542 tgen_ensure(dp[n] >= 0,
"math: no such partition");
2546 for (
int i = 1; i <= n; ++i)
2547 dp_pref[i] = _detail::add_log_space(dp_pref[i - 1], dp[i]);
2549 std::vector<
int> part;
2553 int l = std::max(0, sum - *part_r), r = sum - part_l;
2554 tgen::_detail::tgen_ensure_against_bug(r >= 0,
2555 "math: r < 0 in gen_partition");
2557 int nxt_sum = std::min(sum, r);
2558 long double random = next<
long double>(0, 1);
2569 long double val_l = l ? dp_pref[l - 1] : _detail::LOG_ZERO,
2571 while (nxt_sum > l
and
2572 dp_pref[nxt_sum - 1] >=
2573 val_r + _detail::log_space(random + (1 - random) *
2574 exp(val_l - val_r)))
2577 part.push_back(sum - nxt_sum);
2590 std::optional<
int> part_r = std::nullopt) {
2593 part_r = std::min(*part_r, n);
2595 "math: invalid parameters to gen_partition_fixed_size");
2596 tgen_ensure(
static_cast<
long long>(k) * part_l <= n
and
2597 n <=
static_cast<
long long>(k) * (*part_r),
2598 "math: no such partition");
2601 int s = n - k * part_l;
2603 std::vector<
int> part(k);
2606 std::vector<
int> cuts = {-1};
2608 int total = s + k - 1, bars = k - 1;
2609 for (
int i = 0; i < total
and bars > 0; ++i)
2610 if (next<
long double>(0, 1) <
2611 static_cast<
long double>(bars) / (total - i)) {
2615 cuts.push_back(total);
2618 for (
int i = 0; i < k; ++i)
2619 part[i] = cuts[i + 1] - cuts[i] - 1;
2622 int u = *part_r - part_l;
2625 std::vector<std::vector<
long double>> dp(
2626 k + 1, std::vector<
long double>(s + 1, _detail::LOG_ZERO));
2627 dp[0][0] = _detail::LOG_ONE;
2629 for (
int i = 1; i <= k; ++i) {
2630 std::vector<
long double> pref = dp[i - 1];
2631 for (
int j = 1; j <= s; ++j)
2632 pref[j] = _detail::add_log_space(pref[j - 1], dp[i - 1][j]);
2634 for (
int j = 0; j <= s; ++j) {
2638 _detail::sub_log_space(dp[i][j], pref[j - u - 1]);
2643 int left_to_distribute = s;
2644 for (
int i = k; i >= 1; --i) {
2645 long double log_total = _detail::LOG_ZERO;
2646 for (
int j = 0; j <= u
and j <= left_to_distribute; ++j)
2647 log_total = _detail::add_log_space(
2648 log_total, dp[i - 1][left_to_distribute - j]);
2649 tgen::_detail::tgen_ensure_against_bug(
2650 log_total != _detail::LOG_ZERO,
2651 "math: total == 0 in gen_partition_fixed_size");
2657 long double random =
2658 _detail::log_space(next<
long double>(0, 1)) + log_total;
2660 long double cur_prob = _detail::LOG_ZERO;
2662 for (
int j = 0; j <= u
and j <= left_to_distribute; ++j) {
2663 cur_prob = _detail::add_log_space(
2664 cur_prob, dp[i - 1][left_to_distribute - j]);
2665 if (random < cur_prob) {
2671 part[k - i] = chosen;
2672 left_to_distribute -= chosen;
2684
2685
2686
2687
2690
2691
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2734 std::vector<regex_node> children_;
2735 int left_bound_, right_bound_;
2738 log_space_num_ways_;
2743 regex_node(
const std::string &pattern)
2744 : pattern_(pattern), left_bound_(-1), right_bound_(-1) {
2745 if (pattern.size() == 1) {
2746 log_space_num_ways_ = math::_detail::LOG_ONE;
2749 tgen_ensure_against_bug(pattern[0] ==
'[' and pattern.back() ==
']',
2750 "str: invalid regex: expected character class");
2751 int size = pattern.size() - 2;
2752 log_space_num_ways_ = math::_detail::log_space(size);
2753 distinct_ = unique_container<
char>(pattern.substr(1, size));
2756 regex_node(
const std::string &pattern, std::vector<regex_node> &children)
2757 : pattern_(pattern), left_bound_(-1), right_bound_(-1) {
2758 if (pattern ==
"SEQ") {
2760 log_space_num_ways_ = math::_detail::LOG_ONE;
2761 for (
const auto &child : children)
2762 log_space_num_ways_ += child.log_space_num_ways_;
2763 }
else if (pattern ==
"OR") {
2765 log_space_num_ways_ = math::_detail::LOG_ZERO;
2766 for (
const auto &child : children)
2767 log_space_num_ways_ = math::_detail::add_log_space(
2768 log_space_num_ways_, child.log_space_num_ways_);
2770 tgen_ensure_against_bug(
"str: invalid regex: expected SEQ or OR");
2772 children_ = std::move(children);
2776 regex_node(
int left_bound,
int right_bound, regex_node &child)
2777 : pattern_(
"REP"), left_bound_(left_bound), right_bound_(right_bound) {
2778 log_space_num_ways_ = math::_detail::LOG_ZERO;
2779 for (
int i = left_bound; i <= right_bound; i++)
2780 log_space_num_ways_ = math::_detail::add_log_space(
2781 log_space_num_ways_, i * child.log_space_num_ways_);
2783 children_.push_back(std::move(child));
2789 std::vector<regex_node> cur;
2790 std::vector<regex_node> branches;
2794inline regex_node make_regex_seq(regex_state &st) {
2795 return regex_node(
"SEQ", st.cur);
2799inline regex_node finish_regex_state(regex_state &st) {
2801 if (st.branches.empty())
2802 return make_regex_seq(st);
2805 st.branches.push_back(make_regex_seq(st));
2806 return regex_node(
"OR", st.branches);
2811inline regex_node parse_regex(std::string regex) {
2812 std::string new_regex;
2813 for (
char c : regex)
2816 swap(regex, new_regex);
2818 std::vector<regex_state> stack;
2820 for (size_t i = 0; i < regex.size(); i++) {
2825 stack.push_back(std::move(cur));
2826 cur = regex_state();
2827 }
else if (c ==
')') {
2829 regex_node node = finish_regex_state(cur);
2831 tgen_ensure(!stack.empty(),
"str: invalid regex: unmatched `)`");
2832 cur = std::move(stack.back());
2835 cur.cur.push_back(std::move(node));
2836 }
else if (c ==
'|') {
2838 regex_node node = make_regex_seq(cur);
2839 cur.branches.push_back(std::move(node));
2840 }
else if (c ==
'[') {
2844 for (++i; i < regex.size()
and regex[i] !=
']'; ++i) {
2845 if (i + 2 < regex.size()
and regex[i + 1] ==
'-') {
2846 char a = regex[i], b = regex[i + 2];
2849 for (
char x = a; x <= b; x++)
2857 "str: invalid regex: unmatched `[`");
2858 cur.cur.emplace_back(
"[" + chars +
"]");
2859 }
else if (c ==
'{') {
2864 while (i < regex.size()
and
2865 isdigit(
static_cast<
unsigned char>(regex[i]))) {
2869 "str: invalid regex: number too large inside `{}`");
2870 l = 10 * l + (regex[i] -
'0');
2874 if (i < regex.size()
and regex[i] ==
',') {
2876 while (i < regex.size()
and
2877 isdigit(
static_cast<
unsigned char>(regex[i]))) {
2881 r <=
static_cast<
int>(1e8),
2882 "str: invalid regex: number too large inside `{}`");
2883 r = 10 * r + (regex[i] -
'0');
2890 "str: invalid regex: unmatched `{`");
2892 "str: invalid regex: missing number inside `{}`");
2893 tgen_ensure(l <= r,
"invalid regex: invalid range inside `{}`");
2897 "str: invalid regex: expected expression before `{}`");
2899 regex_node rep(l, r, cur.cur.back());
2901 cur.cur.push_back(std::move(rep));
2904 cur.cur.emplace_back(std::string(1, c));
2908 tgen_ensure(stack.empty(),
"str: invalid regex: unmatched `(`");
2909 return finish_regex_state(cur);
2913inline void gen_regex(
const regex_node &node, std::string &str) {
2915 if (node.pattern_[0] ==
'[') {
2916 str += node.pattern_[1 + next<
int>(0, node.pattern_.size() - 3)];
2921 if (node.left_bound_ != -1) {
2925 double log_rand = math::_detail::log_space(next<
double>(0, 1)) +
2926 node.log_space_num_ways_;
2927 double cur_prob = math::_detail::LOG_ZERO;
2928 double child_num_ways = node.children_[0].log_space_num_ways_;
2930 for (
int i = node.left_bound_; i <= node.right_bound_; ++i) {
2932 math::_detail::add_log_space(cur_prob, i * child_num_ways);
2933 if (log_rand <= cur_prob) {
2934 for (
int j = 0; j < i; ++j)
2935 gen_regex(node.children_[0], str);
2940 tgen_ensure_against_bug(
false,
2941 "str: log_rand > cur_prob in REP gen_regex");
2945 if (!node.children_.empty()
and node.pattern_ ==
"SEQ") {
2946 for (
const regex_node &child : node.children_)
2947 gen_regex(child, str);
2952 if (!node.children_.empty()
and node.pattern_ ==
"OR") {
2956 double log_rand = math::_detail::log_space(next<
double>(0, 1)) +
2957 node.log_space_num_ways_;
2958 double cur_prob = math::_detail::LOG_ZERO;
2960 for (
const regex_node &child : node.children_) {
2961 cur_prob = math::_detail::add_log_space(cur_prob,
2962 child.log_space_num_ways_);
2963 if (log_rand <= cur_prob) {
2964 gen_regex(child, str);
2969 tgen_ensure_against_bug(
false,
2970 "str: log_rand > cur_prob in OR gen_regex");
2974 _detail::tgen_ensure_against_bug(
2975 node.pattern_.size() == 1,
2976 "str: invalid regex: expected single character, but got `" +
2977 node.pattern_ +
"`");
2978 str += node.pattern_[0];
2982template <
typename... Args>
2983std::string regex_format(
const std::string &s, Args &&...args) {
2984 if constexpr (
sizeof...(Args) == 0) {
2987 int size = std::snprintf(
nullptr, 0, s.c_str(), args...) + 1;
2988 std::string buf(size,
'\0');
2989 std::snprintf(buf.data(), size, s.c_str(), args...);
2997inline int hash_string(
const std::string &s,
int base,
int mod) {
3000 h = (h * base + c -
'a' + 1) % mod;
3005inline int estimate_length(
int alphabet_size,
int mod) {
3007 double base_len = 2.5 * std::log(std::sqrt(
static_cast<
double>(mod)));
3008 double scale = std::log(
static_cast<
double>(alphabet_size)) / std::log(2.0);
3009 double adjusted = base_len / std::max(1.0, scale * 0.7);
3011 return static_cast<
int>(std::ceil(adjusted));
3016inline std::pair<std::string, std::string>
3017birthday_attack(
const std::vector<std::string> &alphabet,
int base,
int mod) {
3019 "birthday_attack: base must be in (0, mod)");
3020 std::map<uint64_t, std::vector<
int>> seen;
3021 int length = estimate_length(alphabet.size(), mod);
3024 std::vector<
int> seq(length);
3027 s.reserve(length * alphabet[0].size());
3029 for (
int i = 0; i < length; i++) {
3030 seq[i] = next<
int>(0, alphabet.size() - 1);
3031 s += alphabet[seq[i]];
3034 int h = hash_string(s, base, mod);
3036 auto it = seen.find(h);
3037 if (it != seen.end()
and it->second != seq) {
3040 for (
int x : it->second)
3056 std::optional<
sequence<
char>> seq_;
3057 std::optional<_detail::regex_node>
3062 str(
int size,
char value_l =
'a',
char value_r =
'z')
3070 template <
typename... Args>
str(
const std::string ®ex, Args &&...args) {
3071 tgen_ensure(regex.size() > 0,
"str: regex must be non-empty");
3073 root_ = _detail::parse_regex(
3074 _detail::regex_format(regex, std::forward<Args>(args)...));
3079 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3080 seq_->fix(idx, character);
3086 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3087 seq_->equal(idx_1, idx_2);
3093 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3094 seq_->equal_range(left, right);
3100 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3101 tgen_ensure(0 <= left
and left <= right
and right < seq_->size_,
3102 "str: range indices bust be valid");
3103 for (
int i = left; i < right - (i - left); ++i)
3110 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3111 return palindrome(0, seq_->size_ - 1);
3117 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3118 seq_->distinct(indices);
3124 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3125 seq_->different(idx_1, idx_2);
3131 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3139 using tgen_is_sequential_tag = _detail::is_sequential_tag;
3140 using tgen_has_subset_defined_tag = _detail::has_subset_defined_tag;
3142 using value_type =
char;
3143 using std_type = std::string;
3147 tgen_ensure(!str_.empty(),
"str: instance: cannot be empty");
3151 int size()
const {
return str_.size(); }
3156 "str: instane: index out of bounds");
3159 const char &operator[](
int idx)
const {
3161 "str: instance: index out of bounds");
3168 std::sort(str_.begin(), str_.end());
3175 std::reverse(str_.begin(), str_.end());
3182 for (
char &c : str_)
3183 c = std::tolower(c);
3190 for (
char &c : str_)
3191 c = std::toupper(c);
3202 friend std::ostream &operator<<(std::ostream &out,
3204 return out << inst.str_;
3217 std::string ret_str;
3218 gen_regex(*root_, ret_str);
3222 std::vector<
char> vec = seq_->gen().to_std();
3223 return instance(std::string(vec.begin(), vec.end()));
3231 std::string str =
"a";
3233 while (
static_cast<
int>(str.size()) < n) {
3234 int prev_size = str.size();
3236 for (
int j = 0; j < prev_size
and static_cast<
int>(str.size()) < n;
3250 for (
int i = 0; i < size; ++i) {
3251 a +=
'a' + math::_detail::popcount(i) % 2;
3252 b +=
'a' + (
'b' - a[i]);
3263 "str: alphabet size must be greater than 1");
3264 tgen_ensure(0 < base
and base < mod,
"str: base must be in (0, mod)");
3266 std::vector<std::string> alphabet(alphabet_size);
3267 for (
int i = 0; i < alphabet_size; ++i)
3268 alphabet[i] = std::string(1,
'a' + i);
3269 std::iota(alphabet.begin(), alphabet.end(),
'a');
3270 return _detail::birthday_attack(alphabet, base, mod);
3279 std::vector<
int> mods) {
3281 "str: bases and mods must have the same size");
3283 "str: must have at least one (base, mod) pair");
3284 tgen_ensure(bases.size() <= 2,
"str: multi-hash hack only supported "
3285 "for up to 2 (base, mod) pairs");
3287 std::vector<std::string> alphabet(alphabet_size);
3288 for (
int i = 0; i < alphabet_size; ++i)
3289 alphabet[i] = std::string(1,
'a' + i);
3290 auto [S1, T1] = _detail::birthday_attack(alphabet, bases[0], mods[0]);
3291 if (bases.size() == 1)
3293 return _detail::birthday_attack({S1, T1}, bases[1], mods[1]);
3298
3299
3300
3301
3309inline std::set<
long long> get_hash_hack_multipliers() {
3310 std::set<
long long> multipliers = {85229};
3313 bool codeforces_gcc_case =
true;
3314 if (tgen::_detail::cpp.version_ != 0
and tgen::_detail::cpp.version_ != 17)
3315 codeforces_gcc_case =
false;
3316 if (tgen::_detail::compiler.kind_ !=
3317 tgen::_detail::compiler_kind::unknown
and
3318 tgen::_detail::compiler.kind_ != tgen::_detail::compiler_kind::gcc)
3319 codeforces_gcc_case =
false;
3320 if (tgen::_detail::compiler.major_ > 7)
3321 codeforces_gcc_case =
false;
3322 if (codeforces_gcc_case)
3323 multipliers.insert(107897);
3333 tgen_ensure(size > 0,
"misc: unordered_hack: size must be positive");
3334 std::set<
long long> multipliers = _detail::get_hash_hack_multipliers();
3336 std::set<
long long>::iterator it = multipliers.begin();
3338 std::vector<
long long> list;
3339 while (
static_cast<
int>(list.size()) < size) {
3340 list.push_back(mult * (*it));
3342 if (it == multipliers.end()) {
3343 it = multipliers.begin();
3355 "misc: parenthesis: size must a positive even number");
3359 int open = 0, close = 0;
3361 for (
int i = 0; i < size; ++i) {
3367 if (open == close) {
3373 long long a = k - open, b = k - close, h = open - close;
3378 long long num = a * (h + 2);
3379 long long den = (a + b) * (h + 1);
3381 if (next<
long long>(1, den) <= num) {
C::value_type any(const C &container)
Choses a random element from container.
C shuffled(const C &container)
Shuffles a container.
void shuffle(It first, It last)
Shuffles range inplace, for random_access_iterator.
T next(T n)
Returns a random number up to value.
size_t next_by_distribution(const std::vector< T > &distribution)
Returns random index with given probabilities.
It::value_type any(It first, It last)
Choses a random element from iterator range.
T next(T l, T r)
Returns a random number in range.
#define tgen_ensure(cond,...)
Ensures condition is true.
C choose(int k, const C &container)
Chooses elements from container, as in a subsequence fixed length.
C::value_type any_by_distribution(const C &container, std::vector< T > distribution)
Choses a random element with given probabilities.
Inst::value_type any_by_distribution(const Inst &inst, const std::vector< T > &distribution)
Choses a random element from the sequence instance.
void shuffle(Inst &inst)
Shuffles a sequence instance.
uint64_t congruent_from(uint64_t l, uint64_t rem, uint64_t mod)
Computes smallest congruent from given value.
uint64_t congruent_upto(uint64_t r, uint64_t rem, uint64_t mod)
Computes largest congruent up to given value.
uint64_t congruent_from(uint64_t l, std::vector< uint64_t > rems, std::vector< uint64_t > mods)
Computes smallest congruent from given value.
std::pair< uint64_t, uint64_t > prime_gap_upto(uint64_t r)
Largest prime gap up to given number.
uint64_t prime_upto(uint64_t r)
Computes largest prime up to given value.
uint64_t totient(uint64_t n)
Euler's totient function.
uint64_t prime_from(uint64_t l)
Computes smallest prime from given value.
std::vector< uint64_t > factor(uint64_t n)
Factors a number into primes.
int num_divisors(uint64_t n)
Computes the number of divisors of a given number.
bool is_prime(uint64_t n)
Checks if a number is prime.
uint64_t gen_prime(uint64_t l, uint64_t r)
Generates a random prime in given range.
constexpr int FFT_MOD
FFT/NTT mod.
uint64_t gen_congruent(uint64_t l, uint64_t r, uint64_t rem, uint64_t mod)
Generates random number in range given a modular congruence.
uint64_t gen_congruent(uint64_t l, uint64_t r, std::vector< uint64_t > rems, std::vector< uint64_t > mods)
Generates random number in range given modular congruences.
std::vector< int > gen_partition_fixed_size(int n, int k, int part_l=0, std::optional< int > part_r=std::nullopt)
Generates a random partition with fixed size of a number.
uint64_t highly_composite_upto(uint64_t r)
Largest highly composite number up to given number.
std::vector< int > gen_partition(int n, int part_l=1, std::optional< int > part_r=std::nullopt)
Generates a random partition of a number.
std::vector< std::pair< uint64_t, int > > factor_by_prime(uint64_t n)
Factors a number into primes and its powers.
const std::vector< uint64_t > & fibonacci()
Fetches Fibonacci numbers.
uint64_t modular_inverse(uint64_t a, uint64_t mod)
Computes modular inverse.
uint64_t gen_divisor_count(uint64_t l, uint64_t r, int divisor_count)
Generates random number in range with a given prime number of divisors.
const std::vector< uint64_t > & highly_composites()
Fetches highly composite numbers.
uint64_t congruent_upto(uint64_t r, std::vector< uint64_t > rems, std::vector< uint64_t > mods)
Computes largest congruent up to given value.
std::string gen_parenthesis(int size)
Generates a random valid parenthesis sequence.
std::vector< long long > unordered_hack(int size)
List of integers that force collision on stdunordered_set.
T opt(const std::string &key, std::optional< T > default_value=std::nullopt)
Gets opt by key.
void set_compiler(_detail::compiler_value compiler)
Sets compiler.
T opt(size_t index, std::optional< T > default_value=std::nullopt)
Gets opt by key.
bool has_opt(std::size_t index)
Checks if opt at some index exists.
bool has_opt(const std::string &key)
Checks if opt with with some key exists.
void set_cpp_version(int version)
Sets C++ version.
void register_gen(std::optional< long long > seed=std::nullopt)
Sets up the generator without arguments.
void register_gen(int argc, char **argv)
Sets up the generator.
Base class for generators (should not be instantiated).
auto gen_list(int size, Args &&...args) const
Generates a list of several generation calls.
auto unique(Args &&...args) const
Creates unique generator for current generator.
auto gen_until(Pred predicate, int max_tries, Args &&...args) const
Generates a random instance from the valid set until a condition is met.
Base class for generator instances (should not be instantiated).
bool operator<(const Inst &rhs) const
If type is defined for a subset of itself, for tgen generator instance.
If type is associative container.
If type is a tgen generator instance.
If type is a sequence-like tgen generator instance.
instance(const std::vector< int > &vec)
Creates a permutation instance from a std::vector.
std::vector< int > to_std() const
Converts the instance to a std::vector.
const int & operator[](int idx) const
Returns the value at some position of the instance.
int size() const
Returns the size of the permutation instance.
instance & reverse()
Reverses the instance.
instance & add_1()
Adds 1 for printing.
instance & separator(char sep)
Sets separator for printing.
instance & sort()
Sorts the instance in non-decreasing order.
instance & inverse()
Inverse of the permutation.
int parity() const
Parity of the permutation.
permutation & cycles(const std::vector< int > &cycle_sizes)
Restricts generator s.t. cycle sizes are fixed.
instance gen() const
Generates a random instance from the set of valid permutations.
permutation(int size)
Creates permutation generator defined by size.
permutation & fix(int idx, int value)
Restricts generator s.t. value at index is fixed.
Printer helper for standard types.
print(const T &val, char sep=' ')
Cretes a printer object.
Printer helper for standard types, printing on a new line.
println(const T &val, char sep=' ')
Cretes a printer object that prints on a new line.
instance & reverse()
Reverses the instance.
instance operator+(const instance &rhs)
Concatenates two instances.
instance(const std::vector< T > &vec)
Creates a sequence instance from a std::vector.
T & operator[](int idx)
Accesses the value at some position of the instance.
int size() const
Returns the size of the sequence instance.
instance & separator(char sep)
Sets separator for printing.
instance & sort()
Sorts the instance in non-decreasing order.
std::vector< T > to_std() const
Converts the instance to a std::vector.
sequence(int size, std::set< T > values)
Creates sequence generator define by value set.
sequence & distinct(std::set< int > indices)
Restricts generator s.t. all values in index set are distinct.
sequence & different(int idx_1, int idx_2)
Restricts generator s.t. values at two indices are different.
sequence & fix(int idx, T value)
Restricts generator s.t. value at index is fixed.
sequence & distinct()
Restricts generator s.t. all values are distinct.
instance gen() const
Generates a random instance from the set of valid sequences.
sequence & equal_range(int left, int right)
Restricts generator s.t. all values at index range are the same.
sequence & equal(int idx_1, int idx_2)
Restricts generator s.t. values at two indices are the same.
sequence(int size, T value_l, T value_r)
Creates sequence generator define by size and range of values.
instance & uppercase()
Sets all characters to uppercase.
std::string to_std() const
Converts the instance to a std::string.
instance & reverse()
Reverses the instance.
instance & sort()
Sorts the characters in non-decreasing order.
instance operator+(const instance &rhs)
Concatenates two instances.
instance & lowercase()
Sets all characters to lowercase.
instance(const std::string &str)
Creates a string instance from a std::string.
char & operator[](int idx)
Accesses the character at some position of the instance.
int size() const
Returns the size of the string instance.
str & distinct()
Restricts generator s.t. all characters are distinct.
str & different(int idx_1, int idx_2)
Restricts generator s.t. characters at two indices are different.
instance gen() const
Generates a random instance from the set of valid strings.
str & palindrome(int left, int right)
Restricts generator s.t. range is a palindrome.
str & distinct(std::set< int > indices)
Restricts generator s.t. all characters in index set are distinct.
str(const std::string ®ex, Args &&...args)
Creates string generator define by regex.
static std::pair< instance, instance > unsigned_polynomial_hash_hack()
Returns two strings that force polynomial hash collision for power-of-two mod.
str & equal(int idx_1, int idx_2)
Restricts generator s.t. values at two indices are the same.
str(int size, char value_l='a', char value_r='z')
Creates string generator define by size and range of characters.
static instance abacaba(int n)
Returns the prefix of the infinite word "abacabad...".
str & equal_range(int left, int right)
Restricts generator s.t. all values at index range are the same.
str & fix(int idx, char character)
Restricts generator s.t. character at index is fixed.
static std::pair< instance, instance > polynomial_hash_hack(int alphabet_size, int base, int mod)
Returns two strings that force polynomial hash collision given base and mod.
str & palindrome()
Restricts generator s.t. string is a palindrome.
str(int size, std::set< char > chars)
Creates string generator define by character set.
Unique generator for containers.
auto gen_list(int size)
Generates a list of several unique elements.
T gen()
Generates a unique random element from the container.
size_t size() const
Returns the number of elements left to generate.
unique_container(const C &container)
Creates unique generator for elements of the given container.
auto gen_all()
Generates all unique elements left to generate.
Unique generator for integral ranges.
auto gen_list(int size)
Generates a list of several unique values.
T gen()
Generates a unique random value in the defined range.
auto gen_all()
Generates all unique values left to generate.
unique_range(T l, T r)
Creates unique generator for values in given range.
T size() const
Returns the number of values left to generate.
Unique generator for discrete uniform functions.
bool empty()
Checks if there is nothing left to generate.
auto gen_list(int size)
Generates a list of several unique values.
auto gen()
Generates a unique value.
unique(Func func, Args... args)
Generates a unique generator of a discrete uniform function.
auto gen_all()
Generates all unique values left to generate.