2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
45
46
47
48
53using u128 =
unsigned __int128;
57
58
60inline void throw_assertion_error(
const std::string &condition,
61 const std::string &msg) {
62 throw std::runtime_error(
"tgen: " + msg +
" (assertion `" + condition +
65inline void throw_assertion_error(
const std::string &condition) {
66 throw std::runtime_error(
"tgen: assertion `" + condition +
"` failed");
68inline std::runtime_error error(
const std::string &msg) {
69 return std::runtime_error(
"tgen: " + msg);
71inline std::runtime_error contradiction_error(
const std::string &type,
72 const std::string &msg =
"") {
74 std::string error_msg =
75 type +
": invalid " + type +
" (contradicting restrictions)";
77 error_msg +=
": " + msg;
78 return error(error_msg);
80inline std::runtime_error
81complex_restrictions_error(
const std::string &type,
82 const std::string &msg =
"") {
84 std::string error_msg =
85 type +
": cannot represent " + type +
" (complex restrictions)";
87 error_msg +=
": " + msg;
88 return error(error_msg);
90inline void tgen_ensure_against_bug(
bool cond,
const std::string &msg =
"") {
92 std::string error_msg;
94 error_msg =
"tgen: " + msg +
"\n";
95 error_msg +=
"tgen: THERE IS A BUG IN TGEN; PLEASE CONTACT MAINTAINERS";
96 throw std::runtime_error(error_msg);
101#define tgen_ensure(cond, ...)
103 tgen::detail::throw_assertion_error(#cond, ##__VA_ARGS__);
106inline bool registered =
false;
107inline void ensure_registered() {
109 "tgen was not registered! You should call "
110 "tgen::register_gen(argc, argv) before running tgen functions");
116template <
typename T,
typename =
void>
struct is_container : std::false_type {};
118struct is_container<T,
119 std::void_t<
typename std::remove_reference_t<T>::value_type,
120 decltype(std::begin(std::declval<T>())),
121 decltype(std::end(std::declval<T>()))>>
124template <
typename Char,
typename Traits,
typename Alloc>
125struct is_container<std::basic_string<Char, Traits, Alloc>> : std::false_type {
127template <
typename Char,
typename Traits,
typename Alloc>
128struct is_container<
const std::basic_string<Char, Traits, Alloc>>
129 : std::false_type {};
130template <
typename Char,
typename Traits,
typename Alloc>
131struct is_container<std::basic_string<Char, Traits, Alloc> &>
132 : std::false_type {};
133template <
typename Char,
typename Traits,
typename Alloc>
134struct is_container<
const std::basic_string<Char, Traits, Alloc> &>
135 : std::false_type {};
138template <
typename T>
struct is_pair : std::false_type {};
139template <
typename A,
typename B>
140struct is_pair<std::pair<A, B>> : std::true_type {};
142template <
typename T>
struct is_tuple : std::false_type {};
143template <
typename... Ts>
144struct is_tuple<std::tuple<Ts...>> : std::true_type {};
159template <
typename A,
typename B>
164template <
typename... Ts>
169
170
173using is_sequential_tag =
void;
176using has_subset_defined_tag =
void;
179
180
183inline std::mt19937 rng;
186template <
typename>
inline constexpr bool dependent_false_v =
false;
189
190
196 cpp_value(std::optional<
int> version = std::nullopt)
197 : version_(version ? *version : 0) {
199 tgen_ensure(*version == 17
or *version == 20
or *version == 23,
200 "unsupported C++ version (use 17, 20, 23)");
207
208
211enum class compiler_kind { gcc, clang, unknown };
214struct compiler_value {
219 compiler_value(compiler_kind kind = compiler_kind::unknown,
int major = 0,
221 : kind_(kind), major_(major), minor_(minor) {}
223inline compiler_value compiler;
228
229
232template <
typename T>
struct list;
235template <
typename Func,
typename... Args>
struct distinct {
237 std::tuple<Args...> args_;
242 : func_(std::move(func)), args_(std::move(args)...) {}
246 auto generate_distinct(
bool insert) {
247 for (
int i = 0; i < 84 * std::max<
int>(1, seen_.size()); ++i) {
248 T val = std::apply(func_, args_);
249 if (insert ? seen_.insert(val).second : seen_.count(val) == 0)
250 return std::optional<T>(val);
254 return std::optional<T>();
277 auto val = generate_distinct(
true);
281 throw detail::error(
"no more distinct values");
283 template <
typename U>
auto gen(std::initializer_list<U> il) {
284 return gen(std::vector<U>(il));
290 for (
int i = 0; i < size; ++i)
291 res.push_back(gen());
293 return typename list<T>::value(res);
299 bool empty() {
return generate_distinct(
false) == std::nullopt; }
305 auto val = generate_distinct(
true);
311 return typename list<T>::value(res);
315 friend std::ostream &operator<<(std::ostream &out,
const distinct &) {
316 static_assert(detail::dependent_false_v<
distinct>,
317 "cannot print a distinct generator. Maybe you forgot to "
322template <
typename Func,
typename... Args>
323distinct(Func, Args...) ->
distinct<Func, Args...>;
327 const Gen &self()
const {
return *
static_cast<
const Gen *>(
this); }
329 template <
typename... Args>
auto gen_list(
int size, Args &&...args)
const {
330 std::vector<
typename Gen::value> res;
332 for (
int i = 0; i < size; ++i)
333 res.push_back(
static_cast<
const Gen *>(
this)->gen(
334 std::forward<Args>(args)...));
336 return typename list<
typename Gen::value>::value(res);
340 template <
typename Pred,
typename... Args>
341 auto gen_until(Pred predicate,
int max_tries, Args &&...args)
const {
342 for (
int i = 0; i < max_tries; ++i) {
343 typename Gen::value inst =
static_cast<
const Gen *>(
this)->gen(
344 std::forward<Args>(args)...);
350 throw detail::error(
"could not generate value matching predicate");
352 template <
typename Pred,
typename T,
typename... Args>
353 auto gen_until(Pred predicate,
int max_tries, std::initializer_list<T> il,
354 Args &&...args)
const {
355 return gen_until(predicate, max_tries, std::vector<T>(il),
356 std::forward<Args>(args)...);
360 template <
typename... Args>
auto distinct(Args &&...args)
const {
362 [self = self()](
auto &&...inner_args)
mutable ->
decltype(
auto) {
364 std::forward<
decltype(inner_args)>(inner_args)...);
366 std::forward<Args>(args)...);
368 template <
typename T,
typename... Args>
369 auto distinct(std::initializer_list<T> il, Args &&...args)
const {
370 return distinct(std::vector<T>(il), std::forward<Args>(args)...);
374 friend std::ostream &operator<<(std::ostream &out,
const gen_base &) {
376 detail::dependent_false_v<
gen_base>,
377 "cannot print a generator. Maybe you forgot to call `gen()`?");
384 const Inst &self()
const {
return *
static_cast<
const Inst *>(
this); }
387 return self().to_std() < rhs.to_std();
392
393
396template <
typename T,
typename =
void>
399struct is_associative_container<
400 T, std::void_t<
typename T::key_type,
typename T::key_compare>>
409template <
typename T,
typename =
void>
413 T, std::void_t<
typename std::decay_t<T>::tgen_is_sequential_tag>>
417template <
typename T,
typename =
void>
420struct has_subset_defined<
421 T, std::void_t<
typename std::decay_t<T>::tgen_has_subset_defined_tag>>
425
426
432 template <
typename T>
print(
const T &val,
char sep =
' ') {
433 std::ostringstream oss;
434 write(oss, val, sep);
437 template <
typename T>
438 print(
const std::initializer_list<T> &il,
char sep =
' ') {
439 std::ostringstream oss;
440 write(oss, std::vector<T>(il), sep);
443 template <
typename T>
444 print(
const std::initializer_list<std::initializer_list<T>> &il,
446 std::ostringstream oss;
447 std::vector<std::vector<T>> mat;
448 for (
const auto &i : il)
450 write(oss, mat, sep);
454 template <
typename T>
455 void write(std::ostream &os,
const T &val,
char sep =
' ') {
456 if constexpr (detail::
is_pair<T>::value) {
458 write(os, val.first, sep);
460 write(os, val.second, sep);
462 write(os, val.first);
464 write(os, val.second);
466 }
else if constexpr (detail::
is_tuple<T>::value)
467 write_tuple(os, val, sep);
468 else if constexpr (detail::is_container<T>::value)
469 write_container(os, val, sep);
470 else if constexpr (std::is_same_v<T, detail::i128>
or
471 std::is_same_v<T, detail::u128>)
472 write_128_number(os, val);
478 template <
typename T>
void write_128_number(std::ostream &os, T num) {
479 static const long long BASE = 1e18;
487 write_128_number(os, num / BASE);
488 os << std::setw(18) << std::setfill(
'0')
489 <<
static_cast<
long long>(num % BASE);
491 os <<
static_cast<
long long>(num);
494 template <
typename C>
495 void write_container(std::ostream &os,
const C &container,
char sep =
' ') {
498 for (
const auto &e : container) {
507 template <
typename Tuple, size_t... I>
508 void write_tuple_impl(std::ostream &os,
const Tuple &tp,
char sep,
509 std::index_sequence<I...>) {
511 ((os << (first ? (first =
false,
"")
514 : std::string(1, sep))),
515 write(os, std::get<I>(tp),
519 template <
typename T>
520 void write_tuple(std::ostream &os,
const T &tp,
char sep =
' ') {
521 write_tuple_impl(os, tp, sep,
522 std::make_index_sequence<std::tuple_size<T>::value>{});
525 friend std::ostream &operator<<(std::ostream &out,
const print &pr) {
532 template <
typename T>
534 template <
typename T>
535 println(
const std::initializer_list<T> &il,
char sep =
' ')
537 template <
typename T>
538 println(
const std::initializer_list<std::initializer_list<T>> &il,
542 friend std::ostream &operator<<(std::ostream &out,
const println &pr) {
543 return out << pr.s_ <<
'\n';
548
549
553template <
typename T> T
next(T right) {
554 detail::ensure_registered();
555 if constexpr (std::is_integral_v<T>) {
556 tgen_ensure(right >= 1,
"value for `next` must be valid");
557 return std::uniform_int_distribution<T>(0, right - 1)(detail::rng);
558 }
else if constexpr (std::is_floating_point_v<T>) {
559 tgen_ensure(right >= 0,
"value for `next` must be valid");
560 return std::uniform_real_distribution<T>(0, right)(detail::rng);
562 throw detail::error(
"invalid type for next (" +
563 std::string(
typeid(T).name()) +
")");
568template <
typename T> T
next(T left, T right) {
569 detail::ensure_registered();
570 tgen_ensure(left <= right,
"range for `next` must be valid");
571 if constexpr (std::is_integral_v<T>)
572 return std::uniform_int_distribution<T>(left, right)(detail::rng);
573 else if constexpr (std::is_floating_point_v<T>)
574 return std::uniform_real_distribution<T>(left, right)(detail::rng);
576 throw detail::error(
"invalid type for next (" +
577 std::string(
typeid(T).name()) +
")");
584inline u128 next128(u128 total) {
585 tgen_ensure(total > 0,
"next128: total must be positive");
588 u128 limit = (u128(-1) / total) * total;
592 u128 r = ((u128)next<uint64_t>(0, std::numeric_limits<uint64_t>::max())
594 next<uint64_t>(0, std::numeric_limits<uint64_t>::max());
606 tgen_ensure(distribution.size() > 0,
"distribution must be non-empty");
609 std::accumulate(distribution.begin(), distribution.end(), T(0)));
610 for (size_t i = 0; i < distribution.size(); ++i) {
611 if (r < distribution[i])
613 r -= distribution[i];
615 return distribution.size() - 1;
618size_t next_by_distribution(
const std::initializer_list<T> &distribution) {
619 return next_by_distribution(std::vector<T>(distribution));
624template <
typename It>
void shuffle(It first, It last) {
628 for (It i = first + 1; i != last; ++i)
629 std::iter_swap(i, first + next(0,
static_cast<
int>(i - first)));
634template <
typename Inst, std::enable_if_t<is_sequential<Inst>::value,
int> = 0>
636 for (
int i = 0; i < inst.size(); ++i)
637 std::swap(inst[i], inst[next(0, inst.size() - 1)]);
642template <
typename C, std::enable_if_t<!is_generator_value<C>::value,
int> = 0>
644 if constexpr (is_associative_container<C>::value) {
645 std::vector<
typename C::value_type> vec(container.begin(),
647 shuffle(vec.begin(), vec.end());
650 auto new_container = container;
651 shuffle(new_container.begin(), new_container.end());
652 return new_container;
656[[nodiscard]] std::vector<T> shuffled(
const std::initializer_list<T> &il) {
657 return shuffled(std::vector<T>(il));
662template <
typename Inst, std::enable_if_t<is_sequential<Inst>::value,
int> = 0>
664 Inst new_inst = inst;
672 int size = std::distance(first, last);
674 std::advance(it, next(0, size - 1));
680template <
typename C, std::enable_if_t<!is_generator_value<C>::value,
int> = 0>
682 return pick(container.begin(), container.end());
684template <
typename T> T pick(
const std::initializer_list<T> &il) {
685 return pick(std::vector<T>(il));
690template <
typename Inst, std::enable_if_t<is_sequential<Inst>::value,
int> = 0>
692 return inst[next<
int>(0, inst.size() - 1)];
697template <
typename C,
typename T,
698 std::enable_if_t<!is_generator_value<C>::value,
int> = 0>
700 std::vector<T> distribution) {
701 tgen_ensure(container.size() == distribution.size(),
702 "container and distribution must have the same size");
703 auto it = container.begin();
704 std::advance(it, next_by_distribution(distribution));
707template <
typename C,
typename T,
708 std::enable_if_t<!is_generator_value<C>::value,
int> = 0>
709typename C::value_type
710pick_by_distribution(
const C &container,
711 const std::initializer_list<T> &distribution) {
712 return pick_by_distribution(container, std::vector<T>(distribution));
714template <
typename T,
typename U>
715T pick_by_distribution(
const std::initializer_list<T> &il,
716 const std::vector<U> &distribution) {
717 return pick_by_distribution(std::vector<T>(il), distribution);
719template <
typename T,
typename U>
720T pick_by_distribution(
const std::initializer_list<T> &il,
721 const std::initializer_list<U> &distribution) {
722 return pick_by_distribution(std::vector<T>(il),
723 std::vector<U>(distribution));
728template <
typename Inst,
typename T,
729 std::enable_if_t<is_sequential<Inst>::value,
int> = 0>
732 tgen_ensure(
static_cast<size_t>(inst.size()) == distribution.size(),
733 "inst and distribution must have the same size");
734 return inst[next_by_distribution(distribution)];
736template <
typename Inst,
typename T,
737 std::enable_if_t<is_sequential<Inst>::value,
int> = 0>
738typename Inst::value_type
739pick_by_distribution(
const Inst &inst,
740 const std::initializer_list<T> &distribution) {
741 return pick_by_distribution(inst, std::vector<T>(distribution));
746template <
typename C, std::enable_if_t<!is_generator_value<C>::value,
int> = 0>
748 tgen_ensure(0 < k
and k <=
static_cast<
int>(container.size()),
749 "number of elements to choose must be valid");
750 std::vector<
typename C::value_type> new_vec;
752 int need = k, left = container.size();
753 for (
auto cur_it = container.begin(); cur_it != container.end(); ++cur_it) {
754 if (next(1, left--) <= need) {
755 new_container.insert(new_container.end(), *cur_it);
759 return new_container;
762std::vector<T> choose(
const std::initializer_list<T> &il,
int k) {
763 return choose(std::vector<T>(il), k);
769template <
typename Inst, std::enable_if_t<is_sequential<Inst>::value
and
770 has_subset_defined<Inst>::value,
773 tgen_ensure(0 < k
and k <=
static_cast<
int>(inst.size()),
774 "number of elements to choose must be valid");
775 std::vector<
typename Inst::value_type> new_vec;
777 for (
int i = 0; need > 0; ++i) {
778 int left = inst.size() - i;
779 if (next(1, left) <= need) {
780 new_vec.push_back(inst[i]);
784 return Inst(new_vec);
791 std::map<T, T> virtual_list_;
797 T
size()
const {
return num_available_; }
805 T i = next<T>(0,
size() - 1);
808 T vi = virtual_list_.count(i) ? virtual_list_[i] : i;
809 T vj = virtual_list_.count(j) ? virtual_list_[j] : j;
810 virtual_list_[i] = vj;
821 for (
int i = 0; i < size; ++i)
822 res.push_back(
gen());
823 return typename list<T>::value(res);
831 res.push_back(
gen());
832 return typename list<T>::value(res);
838 std::vector<T> list_;
839 distinct_range<size_t> idx_;
842 template <
typename C>
846 distinct_container(
const std::initializer_list<T> &il)
847 : distinct_container(std::vector<T>(il)) {}
854 T
gen() {
return list_[idx_.gen()]; }
860 for (
int i = 0; i < size; ++i)
861 res.push_back(
gen());
862 return typename list<T>::value(res);
870 res.push_back(
gen());
871 return typename list<T>::value(res);
878
879
880
881
884
885
886
887
888
889
890
891
892
893
894
895
896
899
900
904 detail::cpp = detail::cpp_value(version);
908
909
912inline detail::compiler_value gcc(
int major = 0,
int minor = 0) {
913 return {detail::compiler_kind::gcc, major, minor};
917inline detail::compiler_value clang(
int major = 0,
int minor = 0) {
918 return {detail::compiler_kind::clang, major, minor};
922inline void set_compiler(detail::compiler_value compiler) {
923 detail::compiler.kind_ = compiler.kind_;
924 detail::compiler.major_ = compiler.major_;
925 detail::compiler.minor_ = compiler.minor_;
932inline bool process_special_opt_flags(std::string &key) {
934 if (key.find(
"tgen::CPP:") == 0) {
935 int prefix_len = std::string(
"tgen::CPP:").size();
936 tgen_ensure(
static_cast<
int>(key.size()) == prefix_len + 2
and
937 std::isdigit(key[prefix_len])
and
938 std::isdigit(key[prefix_len + 1]),
939 "invalid CPP format");
940 int version = std::stoi(key.substr(prefix_len, 2));
948 size_t prefix_len = 0;
950 if (key.find(
"tgen::GCC") == 0) {
951 kind = compiler_kind::gcc;
952 prefix_len = std::string(
"tgen::GCC").size();
953 }
else if (key.find(
"tgen::CLANG") == 0) {
954 kind = compiler_kind::clang;
955 prefix_len = std::string(
"tgen::CLANG").size();
960 if (key.size() == prefix_len) {
961 set_compiler(compiler_value(kind, 0, 0));
965 tgen_ensure(key[prefix_len] ==
':',
"invalid compiler format");
968 std::string inside = key.substr(prefix_len, key.size() - prefix_len);
969 int major = 0, minor = 0;
971 size_t dot = inside.find(
'.');
972 if (dot == std::string::npos) {
974 std::all_of(inside.begin(), inside.end(), ::isdigit),
975 "invalid compiler version");
976 major = std::stoi(inside);
978 std::string maj = inside.substr(0, dot);
979 std::string min = inside.substr(dot + 1);
982 std::all_of(maj.begin(), maj.end(), ::isdigit)
and
984 "invalid compiler major version");
986 std::all_of(min.begin(), min.end(), ::isdigit)
and
988 "invalid compiler minor version");
990 major = std::stoi(maj);
991 minor = std::stoi(min);
994 set_compiler(compiler_value(kind, major, minor));
999inline std::vector<std::string>
1001inline std::map<std::string, std::string>
1004template <
typename T> T get_opt(
const std::string &value) {
1006 if constexpr (std::is_same_v<T,
bool>) {
1007 if (value ==
"true" or value ==
"1")
1009 if (value ==
"false" or value ==
"0")
1011 }
else if constexpr (std::is_integral_v<T>) {
1012 if constexpr (std::is_unsigned_v<T>)
1013 return static_cast<T>(std::stoull(value));
1015 return static_cast<T>(std::stoll(value));
1016 }
else if constexpr (std::is_floating_point_v<T>)
1017 return static_cast<T>(std::stold(value));
1023 throw error(
"invalid value `" + value +
"` for type " +
typeid(T).name());
1026inline void parse_opts(
int argc,
char **argv) {
1029 for (
int i = 1; i < argc; ++i) {
1030 std::string key(argv[i]);
1032 if (process_special_opt_flags(key))
1035 if (key[0] ==
'-') {
1037 "invalid opt (" + std::string(argv[i]) +
")");
1038 if (
'0' <= key[1]
and key[1] <=
'9') {
1040 pos_opts.push_back(key);
1045 key = key.substr(1);
1048 pos_opts.push_back(key);
1053 if (key[0] ==
'-') {
1055 "invalid opt (" + std::string(argv[i]) +
")");
1058 key = key.substr(1);
1065 std::size_t eq = key.find(
'=');
1066 if (eq != std::string::npos) {
1068 std::string value = key.substr(eq + 1);
1069 key = key.substr(0, eq);
1071 "expected non-empty key/value in opt (" +
1072 std::string(argv[1]));
1074 "cannot have repeated keys");
1075 named_opts[key] = value;
1079 "cannot have repeated keys");
1080 tgen_ensure(argv[i + 1],
"value cannot be empty");
1081 named_opts[key] = std::string(argv[i + 1]);
1087inline void set_seed(
int argc,
char **argv) {
1088 std::vector<uint32_t> seed;
1091 for (
int i = 1; i < argc; ++i) {
1093 int size_pos = seed.size();
1095 for (
char *s = argv[i]; *s !=
'\0'; ++s) {
1100 std::seed_seq seq(seed.begin(), seed.end());
1108 detail::ensure_registered();
1109 return 0 <= index
and index < detail::pos_opts.size();
1114 detail::ensure_registered();
1115 return detail::named_opts.count(key) != 0;
1117template <
typename K>
1118std::enable_if_t<std::is_same_v<K,
char>,
bool> has_opt(K key) {
1124template <
typename T>
1125T
opt(size_t index, std::optional<T> default_value = std::nullopt) {
1126 detail::ensure_registered();
1127 if (!has_opt(index)) {
1129 return *default_value;
1130 throw detail::error(
"cannot find key with index " +
1131 std::to_string(index));
1133 return detail::get_opt<T>(detail::pos_opts[index]);
1138template <
typename T>
1139T
opt(
const std::string &key, std::optional<T> default_value = std::nullopt) {
1140 detail::ensure_registered();
1143 return *default_value;
1144 throw detail::error(
"cannot find key with key " + key);
1146 return detail::get_opt<T>(detail::named_opts[key]);
1148template <
typename T,
typename K>
1149std::enable_if_t<std::is_same_v<K,
char>, T>
1150opt(K key, std::optional<T> default_value = std::nullopt) {
1151 return opt<T>(std::string(1, key), default_value);
1156 detail::set_seed(argc, argv);
1158 detail::pos_opts.clear();
1159 detail::named_opts.clear();
1160 detail::parse_opts(argc, argv);
1162 detail::registered =
true;
1168 detail::rng.seed(*seed);
1172 detail::pos_opts.clear();
1173 detail::named_opts.clear();
1175 detail::registered =
true;
1179
1180
1181
1182
1185
1186
1187
1188
1192 T value_l_, value_r_;
1193 std::set<T> values_;
1198 std::vector<std::pair<T, T>> val_range_;
1199 std::vector<std::vector<
int>> neigh_;
1200 std::vector<std::set<
int>>
1205 list(
int size, T value_left, T value_right)
1206 : size_(size), value_l_(value_left), value_r_(value_right),
1208 tgen_ensure(size_ > 0,
"list: size must be positive");
1209 tgen_ensure(value_l_ <= value_r_,
"list: value range must be valid");
1210 for (
int i = 0; i < size_; ++i)
1211 val_range_.emplace_back(value_l_, value_r_);
1217 tgen_ensure(size_ > 0,
"list: size must be positive");
1218 tgen_ensure(!values.empty(),
"list: value set must be non-empty");
1219 value_l_ = 0, value_r_ = values.size() - 1;
1220 for (
int i = 0; i < size_; ++i)
1221 val_range_.emplace_back(value_l_, value_r_);
1223 for (T val : values_)
1224 value_idx_in_set_[val] = idx++;
1229 tgen_ensure(0 <= idx
and idx < size_,
"list: index must be valid");
1230 if (values_.size() == 0) {
1231 auto &[left, right] = val_range_[idx];
1232 if (left == right
and value_l_ != value_r_) {
1234 "list: must not set to two different values");
1237 "list: value must be in the defined range");
1242 "list: value must be in the set of values");
1243 auto &[left, right] = val_range_[idx];
1244 int new_val = value_idx_in_set_[val];
1246 "list: must not set to two different values");
1247 left = right = new_val;
1255 std::max(idx_1, idx_2) < size_,
1256 "list: indices must be valid");
1260 neigh_[idx_1].push_back(idx_2);
1261 neigh_[idx_2].push_back(idx_1);
1267 if (!indices.empty()) {
1268 std::set<
int>::iterator beg = indices.begin();
1269 for (
auto it = std::next(beg); it != indices.end(); ++it)
1277 tgen_ensure(0 <= left
and left <= right
and right < size_,
1278 "list: range indices must be valid");
1279 for (
int i = left; i < right; ++i)
1291 if (!indices.empty())
1292 diff_restrictions_.push_back(indices);
1298 std::set<
int> indices = {idx_1, idx_2};
1304 tgen_ensure(0 <= left
and left <= right
and right < size_,
1305 "list: range indices must be valid");
1306 std::vector<
int> indices(right - left + 1);
1307 std::iota(indices.begin(), indices.end(), left);
1308 return different(std::set<
int>(indices.begin(), indices.end()));
1313 std::vector<
int> indices(size_);
1314 std::iota(indices.begin(), indices.end(), 0);
1315 return different(std::set<
int>(indices.begin(), indices.end()));
1321 using tgen_is_sequential_tag = detail::is_sequential_tag;
1322 using tgen_has_subset_defined_tag = detail::has_subset_defined_tag;
1324 using value_type = T;
1326 std::vector<T> vec_;
1330 value(
const std::initializer_list<T> &il) : value(std::vector<T>(il)) {}
1333 int size()
const {
return vec_.size(); }
1338 "list: value: index out of bounds");
1341 const T &operator[](
int idx)
const {
1343 "list: value: index out of bounds");
1350 std::sort(vec_.begin(), vec_.end());
1357 std::reverse(vec_.begin(), vec_.end());
1371 std::vector<T> new_vec = vec_;
1372 for (
int i = 0; i < rhs
.size(); ++i)
1373 new_vec.push_back(rhs[i]);
1374 return value(new_vec);
1378 friend std::ostream &operator<<(std::ostream &out,
const value &inst) {
1379 for (
int i = 0; i < inst.size(); ++i) {
1392 std::vector<
typename T::std_type> vec;
1393 for (
const auto &i : vec_)
1394 vec.push_back(i.to_std());
1403 generate_distinct_values(
int k,
const std::set<T> &forbidden_values)
const {
1404 for (
auto forbidden : forbidden_values)
1405 tgen_ensure(value_l_ <= forbidden
and forbidden <= value_r_);
1410 T num_available = (value_r_ - value_l_ + 1) - forbidden_values.size();
1411 if (num_available < k)
1412 throw detail::complex_restrictions_error(
1413 "list",
"not enough distinct values");
1414 std::map<T, T> virtual_list;
1415 std::vector<T> gen_list;
1416 for (
int i = 0; i < k; ++i) {
1417 T j = next<T>(i, num_available - 1);
1418 T vj = virtual_list.count(j) ? virtual_list[j] : j;
1419 T vi = virtual_list.count(i) ? virtual_list[i] : i;
1421 virtual_list[j] = vi, virtual_list[i] = vj;
1423 gen_list.push_back(virtual_list[i]);
1428 for (T &val : gen_list)
1433 std::vector<std::pair<T,
int>> values_sorted;
1434 for (std::size_t i = 0; i < gen_list.size(); ++i)
1435 values_sorted.emplace_back(gen_list[i], i);
1437 std::sort(values_sorted.begin(), values_sorted.end());
1438 auto cur_it = forbidden_values.begin();
1439 int smaller_forbidden_count = 0;
1440 for (
auto [val, idx] : values_sorted) {
1441 while (cur_it != forbidden_values.end()
and
1442 *cur_it <= val + smaller_forbidden_count)
1443 ++cur_it, ++smaller_forbidden_count;
1444 gen_list[idx] += smaller_forbidden_count;
1453 std::vector<T> vec(size_);
1454 std::vector<
bool> defined_idx(
1457 std::vector<
int> comp_id(size_, -1);
1458 std::vector<std::vector<
int>> comp(size_);
1462 auto define_comp = [&](
int cur_comp, T val) {
1463 for (
int idx : comp[cur_comp]) {
1466 defined_idx[idx] =
true;
1472 std::vector<
bool> vis(size_,
false);
1473 for (
int idx = 0; idx < size_; ++idx)
1476 bool value_defined =
false;
1480 std::queue<
int> q({idx});
1482 std::vector<
int> component;
1483 while (!q.empty()) {
1484 int cur_idx = q.front();
1487 component.push_back(cur_idx);
1490 auto [l, r] = val_range_[cur_idx];
1492 if (!value_defined) {
1494 value_defined =
true;
1496 }
else if (new_value != l) {
1498 throw detail::contradiction_error(
1500 "tried to set value to `" +
1501 std::to_string(new_value) +
1502 "`, but it was already set as `" +
1503 std::to_string(l) +
"`");
1507 for (
int nxt_idx : neigh_[cur_idx]) {
1508 if (!vis[nxt_idx]) {
1509 vis[nxt_idx] =
true;
1516 for (
int cur_idx : component) {
1517 comp_id[cur_idx] = comp_count;
1518 comp[comp_id[cur_idx]].push_back(cur_idx);
1523 define_comp(comp_count, new_value);
1530 std::vector<std::set<
int>> diff_containing_comp_idx(comp_count);
1533 for (
const std::set<
int> &diff : diff_restrictions_) {
1535 if (
static_cast<uint64_t>(diff.size() - 1) +
1536 static_cast<uint64_t>(value_l_) >
1537 static_cast<uint64_t>(value_r_))
1538 throw detail::contradiction_error(
1539 "list",
"tried to generate " +
1540 std::to_string(diff.size()) +
1541 " different values, but the maximum is " +
1542 std::to_string(value_r_ - value_l_ + 1));
1546 std::set<
int> comp_ids;
1547 for (
int idx : diff) {
1548 if (comp_ids.count(comp_id[idx]))
1549 throw detail::contradiction_error(
1550 "list",
"tried to set two indices as equal and "
1552 comp_ids.insert(comp_id[idx]);
1554 diff_containing_comp_idx[comp_id[idx]].insert(dist_id);
1561 for (
auto &diff_containing : diff_containing_comp_idx)
1562 if (diff_containing.size() >= 3)
1563 throw detail::complex_restrictions_error(
1565 "one index can not be in >= 3 'different' restrictions");
1567 std::vector<
bool> vis_diff(diff_restrictions_.size(),
false);
1568 std::vector<
bool> initially_defined_comp_idx(comp_count,
false);
1571 auto define_tree = [&](
int diff_id) {
1576 std::set<T> defined_values;
1577 for (
int idx : diff_restrictions_[diff_id])
1578 if (defined_idx[idx]) {
1581 if (defined_values.count(vec[idx]))
1582 throw detail::contradiction_error(
1584 "tried to set two indices as equal and different");
1586 defined_values.insert(vec[idx]);
1591 int new_value_count = diff_restrictions_[diff_id].size() -
1592 static_cast<
int>(defined_values.size());
1593 std::vector<T> generated_values =
1594 generate_distinct_values(new_value_count, defined_values);
1595 auto val_it = generated_values.begin();
1596 for (
int idx : diff_restrictions_[diff_id])
1597 if (defined_idx[idx]) {
1600 initially_defined_comp_idx[comp_id[idx]] =
false;
1602 define_comp(comp_id[idx], *val_it);
1608 std::queue<std::pair<
int,
int>> q;
1609 q.emplace(diff_id, -1);
1610 vis_diff[diff_id] =
true;
1611 while (!q.empty()) {
1612 auto [cur_diff, parent] = q.front();
1615 std::set<
int> neigh_diff;
1616 for (
int idx : diff_restrictions_[cur_diff])
1618 diff_containing_comp_idx[comp_id[idx]]) {
1619 if (nxt_diff == cur_diff
or nxt_diff == parent)
1623 if (vis_diff[nxt_diff])
1624 throw detail::complex_restrictions_error(
1626 "cycle found in 'different' restrictions");
1628 neigh_diff.insert(nxt_diff);
1631 for (
int nxt_diff : neigh_diff) {
1632 vis_diff[nxt_diff] =
true;
1633 q.emplace(nxt_diff, cur_diff);
1636 std::set<T> nxt_defined_values;
1637 for (
int idx2 : diff_restrictions_[nxt_diff])
1638 if (defined_idx[idx2]) {
1642 if (initially_defined_comp_idx[comp_id[idx2]])
1643 throw detail::complex_restrictions_error(
1646 nxt_defined_values.insert(vec[idx2]);
1648 int new_value_count =
1649 diff_restrictions_[nxt_diff].size() -
1650 static_cast<
int>(nxt_defined_values.size());
1651 std::vector<T> generated_values = generate_distinct_values(
1652 new_value_count, nxt_defined_values);
1653 auto val_it = generated_values.begin();
1654 for (
int idx2 : diff_restrictions_[nxt_diff])
1655 if (!defined_idx[idx2]) {
1656 define_comp(comp_id[idx2], *val_it);
1668 std::vector<std::pair<
int,
int>> defined_cnt_and_diff_idx;
1670 for (
const std::set<
int> &diff : diff_restrictions_) {
1671 int defined_cnt = 0;
1672 for (
int idx : diff)
1673 if (defined_idx[idx]) {
1675 initially_defined_comp_idx[comp_id[idx]] =
true;
1677 defined_cnt_and_diff_idx.emplace_back(defined_cnt, dist_id);
1681 std::sort(defined_cnt_and_diff_idx.rbegin(),
1682 defined_cnt_and_diff_idx.rend());
1683 for (
auto [defined_cnt, diff_idx] : defined_cnt_and_diff_idx)
1684 if (!vis_diff[diff_idx])
1685 define_tree(diff_idx);
1689 for (std::size_t dist_id = 0; dist_id < diff_restrictions_.size();
1691 if (!vis_diff[dist_id])
1692 define_tree(dist_id);
1698 for (
int idx = 0; idx < size_; ++idx)
1699 if (!defined_idx[idx])
1700 define_comp(comp_id[idx], next<T>(value_l_, value_r_));
1702 if (!values_.empty()) {
1704 std::vector<T> value_vec(values_.begin(), values_.end());
1706 val = value_vec[val];
1714
1715
1716
1717
1720
1721
1722
1723
1727 std::vector<std::pair<
int,
int>> defs_;
1728 std::optional<std::vector<
int>> cycle_sizes_;
1732 tgen_ensure(size_ > 0,
"permutation: size must be positive");
1738 "permutation: index must be valid");
1739 defs_.emplace_back(idx, val);
1746 size_ == std::accumulate(cycle_sizes.begin(), cycle_sizes.end(), 0),
1747 "permutation: cycle sizes must add up to size of permutation");
1748 cycle_sizes_ = cycle_sizes;
1751 permutation &cycles(
const std::initializer_list<
int> &cycle_sizes) {
1752 return cycles(std::vector<
int>(cycle_sizes));
1758 using tgen_is_sequential_tag = detail::is_sequential_tag;
1761 std::vector<
int> vec_;
1766 :
vec_(
vec), sep_(
' '), add_1_(
false) {
1767 tgen_ensure(!vec_.empty(),
"permutation: value: cannot be empty");
1768 std::vector<
bool> vis(vec_.size(),
false);
1769 for (
int i = 0; i <
size(); ++i) {
1771 vec_[i] <
static_cast<
int>(vec_.size()),
1772 "permutation: value: values must be from `0` to "
1775 "permutation: value: cannot have repeated values");
1776 vis[vec_[i]] =
true;
1779 value(
const std::initializer_list<
int> &il)
1780 : value(std::vector<
int>(il)) {}
1783 int size()
const {
return vec_.size(); }
1788 "permutation: value: index out of bounds");
1795 std::vector<
bool> vis(
size(),
false);
1798 for (
int i = 0; i <
size(); ++i)
1801 for (
int j = i; !vis[j]; j = vec_[j])
1805 return ((
size() - cycles) % 2 == 0) ? +1 : -1;
1811 for (
int i = 0; i < size(); ++i)
1819 std::reverse(vec_.begin(), vec_.end());
1826 std::vector<
int> inv(
size());
1827 for (
int i = 0; i < size(); ++i)
1848 friend std::ostream &operator<<(std::ostream &out,
const value &inst) {
1849 for (
int i = 0; i < inst
.size(); ++i) {
1852 out << inst
[i
] + inst.add_1_;
1864 if (!cycle_sizes_) {
1866 std::vector<
int> idx_to_val(size_, -1), val_to_idx(size_, -1);
1867 for (
auto [idx, val] : defs_) {
1869 0 <= val
and val < size_,
1870 "permutation: value in permutation must be in [0, " +
1871 std::to_string(size_) +
")");
1873 if (idx_to_val[idx] != -1) {
1875 "permutation: cannot set an idex to two "
1876 "different values");
1878 idx_to_val[idx] = val;
1880 if (val_to_idx[val] != -1) {
1882 "permutation: cannot set two indices to the "
1885 val_to_idx[val] = idx;
1888 std::vector<
int> perm(size_);
1889 std::iota(perm.begin(), perm.end(), 0);
1890 shuffle(perm.begin(), perm.end());
1892 for (
int &i : idx_to_val)
1895 while (val_to_idx[perm[cur_idx]] != -1)
1897 i = perm[cur_idx++];
1903 std::vector<
int> order(size_);
1904 std::iota(order.begin(), order.end(), 0);
1905 shuffle(order.begin(), order.end());
1907 std::vector<std::vector<
int>> cycles;
1908 for (
int cycle_size : *cycle_sizes_) {
1909 cycles.emplace_back();
1910 for (
int i = 0; i < cycle_size; ++i)
1911 cycles.back().push_back(order[idx++]);
1915 std::vector<
int> perm(size_, -1);
1916 for (
const std::vector<
int> &cycle : cycles) {
1917 int cur_size = cycle.size();
1918 for (
int i = 0; i < cur_size; ++i)
1919 perm[cycle[i]] = cycle[(i + 1) % cur_size];
1927
1928
1929
1930
1936using namespace tgen::detail;
1938inline int popcount(uint64_t x) {
return __builtin_popcountll(x); }
1940inline int ctzll(uint64_t x) {
1943 static const unsigned char index64[64] = {
1944 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
1945 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
1946 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
1947 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12};
1948 return index64[((x & -x) * 0x022FDD63CC95386D) >> 58];
1951inline uint64_t mul_mod(uint64_t a, uint64_t b, uint64_t m) {
1952 return static_cast<u128>(a) * b % m;
1957inline uint64_t expo_mod(uint64_t x, uint64_t y, uint64_t m) {
1960 uint64_t ans = expo_mod(mul_mod(x, x, m), y / 2, m);
1961 return y % 2 ? mul_mod(x, ans, m) : ans;
1970 if (n == 2
or n == 3)
1975 uint64_t r = detail::ctzll(n - 1), d = n >> r;
1977 for (
int a : {2, 325, 9375, 28178, 450775, 9780504, 1795265022}) {
1978 uint64_t x = detail::expo_mod(a, d, n);
1979 if (x == 1
or x == n - 1
or a % n == 0)
1982 for (uint64_t j = 0; j < r - 1; ++j) {
1983 x = detail::mul_mod(x, x, n);
1995inline uint64_t pollard_rho(uint64_t n) {
1998 auto f = [n](uint64_t x) {
return mul_mod(x, x, n) + 1; };
2000 uint64_t x = 0, y = 0, t = 30, prd = 2, x0 = 1, q;
2001 while (t % 40 != 0
or std::gcd(prd, n) == 1) {
2004 q = mul_mod(prd, x > y ? x - y : y - x, n);
2007 x = f(x), y = f(f(y)), t++;
2009 return std::gcd(prd, n);
2012inline std::vector<uint64_t> factor(uint64_t n) {
2017 uint64_t d = pollard_rho(n);
2018 std::vector<uint64_t> l = factor(d), r = factor(n / d);
2019 l.insert(l.end(), r.begin(), r.end());
2024template <
typename T>
2025std::runtime_error there_is_no_in_range_error(
const std::string &type, T l,
2027 return error(
"math: there is no " + type +
" in range [" +
2028 std::to_string(l) +
", " + std::to_string(r) +
"]");
2030template <
typename T>
2031std::runtime_error there_is_no_from_error(
const std::string &type, T r) {
2032 return error(
"math: there is no " + type +
" from " + std::to_string(r));
2034template <
typename T>
2035std::runtime_error there_is_no_upto_error(
const std::string &type, T r) {
2036 return error(
"math: there is no " + type +
" up to " + std::to_string(r));
2042inline i128 modular_inverse_128(i128 a, i128 mod) {
2044 "math: remainder must be positive and smaller than the mod");
2046 i128 t = 0, new_t = 1;
2047 i128 r = mod, new_r = a;
2049 while (new_r != 0) {
2052 auto tmp_t = t - q * new_t;
2056 auto tmp_r = r - q * new_r;
2061 tgen_ensure(r == 1,
"math: remainder and mod must be coprime");
2069inline bool mul_leq(uint64_t a, uint64_t b, uint64_t limit) {
2072 return a <= limit / b;
2076inline std::optional<uint64_t> expo(uint64_t base, uint64_t exp,
2078 uint64_t result = 1;
2082 if (!mul_leq(result, base, limit))
2083 return std::nullopt;
2092 if (!mul_leq(base, base, limit))
2093 return std::nullopt;
2101inline uint64_t kth_root_floor(uint64_t n, uint64_t k) {
2102 tgen_ensure_against_bug(k > 0,
"math: value must be valid");
2103 if (k == 1
or n <= 1)
2106 uint64_t lo = 1, hi = 1ULL << ((64 + k - 1) / k);
2109 uint64_t mid = lo + (hi - lo + 1) / 2;
2111 if (expo(mid, k, n)) {
2122inline i128 gcd128(i128 a, i128 b) {
2138inline i128 mul_saturate(i128 a, i128 b) {
2140 static const i128 LIMIT =
static_cast<i128>(1) << 64;
2141 if (a == 0
or b == 0)
2152 crt() : a(0), m(1) {}
2153 crt(T a_, T m_) : a(a_), m(m_) {}
2154 crt operator*(crt C) {
2155 if (m == 0
or C.m == 0)
2158 T g = gcd128(m, C.m);
2159 if ((C.a - a) % g != 0)
2168 T inv = modular_inverse_128(m1 % m2, m2);
2170 T k = ((C.a - a) / g) % m2;
2174 k =
static_cast<u128>(k) * inv % m2;
2176 T lcm = mul_saturate(m, m2);
2178 T res = (a +
static_cast<T>((
static_cast<u128>(k) * m) % lcm)) % lcm;
2188inline constexpr long double LOG_ZERO = -INFINITY;
2189inline constexpr long double LOG_ONE = 0.0;
2191inline long double log_space(
long double x) {
2192 return x == 0.0 ? LOG_ZERO : std::log(x);
2196inline long double add_log_space(
long double a,
long double b) {
2205 return a + log1p(exp(b - a));
2210inline long double sub_log_space(
long double a,
long double b) {
2215 return a + log1p(-exp(b - a));
2224 tgen_ensure(n > 0,
"math: number to factor must be positive");
2225 auto factors = detail::factor(n);
2226 std::sort(factors.begin(), factors.end());
2234 tgen_ensure(n > 0,
"math: number to factor must be positive");
2235 std::vector<std::pair<uint64_t,
int>> primes;
2236 for (uint64_t p : factor(n)) {
2237 if (!primes.empty()
and primes.back().first == p)
2238 ++primes.back().second;
2240 primes.emplace_back(p, 1);
2249 return detail::modular_inverse_128(a, mod);
2255 tgen_ensure(n > 0,
"math: totient(0) is undefined");
2258 for (
auto [p, e] : factor_by_prime(n))
2265inline const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> &
2268 static const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> value{
2270 2, 3, 7, 23, 89, 113, 523, 887, 1129, 1327, 9551, 15683, 19609,
2271 31397, 155921, 360653, 370261, 492113, 1349533, 1357201, 2010733,
2272 4652353, 17051707, 20831323, 47326693, 122164747, 189695659,
2273 191912783, 387096133, 436273009, 1294268491, 1453168141,
2274 2300942549, 3842610773, 4302407359, 10726904659, 20678048297,
2275 22367084959, 25056082087, 42652618343, 127976334671, 182226896239,
2276 241160624143, 297501075799, 303371455241, 304599508537,
2277 416608695821, 461690510011, 614487453523, 738832927927,
2278 1346294310749, 1408695493609, 1968188556461, 2614941710599,
2279 7177162611713, 13829048559701, 19581334192423, 42842283925351,
2280 90874329411493, 171231342420521, 218209405436543, 1189459969825483,
2281 1686994940955803, 1693182318746371, 43841547845541059,
2282 55350776431903243, 80873624627234849, 203986478517455989,
2283 218034721194214273, 305405826521087869, 352521223451364323,
2284 401429925999153707, 418032645936712127, 804212830686677669,
2285 1425172824437699411, 5733241593241196731, 6787988999657777797
2287 {1, 2, 4, 6, 8, 14, 18, 20, 22, 34, 36,
2288 44, 52, 72, 86, 96, 112, 114, 118, 132, 148, 154,
2289 180, 210, 220, 222, 234, 248, 250, 282, 288, 292, 320,
2290 336, 354, 382, 384, 394, 456, 464, 468, 474, 486, 490,
2291 500, 514, 516, 532, 534, 540, 582, 588, 602, 652, 674,
2292 716, 766, 778, 804, 806, 906, 916, 924, 1132, 1184, 1198,
2293 1220, 1224, 1248, 1272, 1328, 1356, 1370, 1442, 1476, 1488, 1510}};
2302 throw detail::there_is_no_upto_error(
"prime gap", right);
2304 const auto &[P, G] = prime_gaps();
2305 for (
int i = P.size() - 1;; --i) {
2309 uint64_t real_right = std::min(right, P[i] + G[i] - 1);
2310 uint64_t prev = i > 0 ? G[i - 1] : 0;
2311 uint64_t curr = real_right - P[i];
2314 return {P[i] + 1, real_right};
2321 static const std::vector<uint64_t> highly_composites = {
2322 1, 2, 4, 6, 12, 24, 36, 48, 60, 120, 180, 240, 360, 720, 840, 1260, 1680,
2323 2520, 5040, 7560, 10080, 15120, 20160, 25200, 27720, 45360, 50400, 55440,
2324 83160, 110880, 166320, 221760, 277200, 332640, 498960, 554400, 665280,
2325 720720, 1081080, 1441440, 2162160, 2882880, 3603600, 4324320, 6486480,
2326 7207200, 8648640, 10810800, 14414400, 17297280, 21621600, 32432400,
2327 36756720, 43243200, 61261200, 73513440, 110270160, 122522400, 147026880,
2328 183783600, 245044800, 294053760, 367567200, 551350800, 698377680, 735134400,
2329 1102701600, 1396755360, 2095133040, 2205403200, 2327925600, 2793510720,
2330 3491888400, 4655851200, 5587021440, 6983776800, 10475665200, 13967553600,
2331 20951330400, 27935107200, 41902660800, 48886437600, 64250746560,
2332 73329656400, 80313433200, 97772875200, 128501493120, 146659312800,
2333 160626866400, 240940299600, 293318625600, 321253732800, 481880599200,
2334 642507465600, 963761198400, 1124388064800, 1606268664000, 1686582097200,
2335 1927522396800, 2248776129600, 3212537328000, 3373164194400, 4497552259200,
2336 6746328388800, 8995104518400, 9316358251200, 13492656777600, 18632716502400,
2337 26985313555200, 27949074753600, 32607253879200, 46581791256000,
2338 48910880818800, 55898149507200, 65214507758400, 93163582512000,
2339 97821761637600, 130429015516800, 195643523275200, 260858031033600,
2340 288807105787200, 391287046550400, 577614211574400, 782574093100800,
2341 866421317361600, 1010824870255200, 1444035528936000, 1516237305382800,
2342 1732842634723200, 2021649740510400, 2888071057872000, 3032474610765600,
2343 4043299481020800, 6064949221531200, 8086598962041600, 10108248702552000,
2344 12129898443062400, 18194847664593600, 20216497405104000, 24259796886124800,
2345 30324746107656000, 36389695329187200, 48519593772249600, 60649492215312000,
2346 72779390658374400, 74801040398884800, 106858629141264000,
2347 112201560598327200, 149602080797769600, 224403121196654400,
2348 299204161595539200, 374005201994424000, 448806242393308800,
2349 673209363589963200, 748010403988848000, 897612484786617600,
2350 1122015605983272000, 1346418727179926400, 1795224969573235200,
2351 2244031211966544000, 2692837454359852800, 3066842656354276800,
2352 4381203794791824000, 4488062423933088000, 6133685312708553600,
2353 8976124847866176000, 9200527969062830400, 12267370625417107200ULL,
2354 15334213281771384000ULL, 18401055938125660800ULL};
2355 return highly_composites;
2360 for (
int i = highly_composites().size() - 1; i >= 0; --i)
2361 if (highly_composites()[i] <= right)
2362 return highly_composites()[i];
2364 throw detail::there_is_no_upto_error(
"highly composite number", right);
2370 if (right < left
or right < 2)
2371 throw detail::there_is_no_in_range_error(
"prime", left, right);
2372 left = std::max<uint64_t>(left, 2);
2373 auto [l_gap, r_gap] = prime_gap_upto(right);
2374 if (right - left + 1 <= r_gap - l_gap + 1) {
2376 std::vector<uint64_t> vals(right - left + 1);
2377 iota(vals.begin(), vals.end(), left);
2378 shuffle(vals.begin(), vals.end());
2379 for (uint64_t i : vals)
2382 throw detail::there_is_no_in_range_error(
"prime", left, right);
2387 n = next(left, right);
2395 tgen_ensure(left <= std::numeric_limits<uint64_t>::max() - 58,
2396 "math: invalid bound");
2397 for (uint64_t i = std::max<uint64_t>(2, left);; ++i)
2405 for (uint64_t i = right; i >= 2; --i)
2408 throw detail::there_is_no_upto_error(
"prime", right);
2415 for (
auto [p, e] : factor_by_prime(n))
2416 divisors *= (e + 1);
2424 int divisor_count) {
2426 "math: divisor count must be prime");
2427 int root = divisor_count - 1;
2428 uint64_t p =
gen_prime(detail::kth_root_floor(left, root)
,
2429 detail::kth_root_floor(right, root)
);
2430 return *detail::expo(p, root, right);
2437 std::vector<uint64_t> rems,
2438 std::vector<uint64_t> mods) {
2440 throw detail::there_is_no_in_range_error(
"congruent number", left,
2443 "math: number of remainders and mods must be the same");
2444 tgen_ensure(rems.size() > 0,
"math: must have at least one congruence");
2447 for (
int i = 0; i <
static_cast<
int>(rems.size()); ++i) {
2449 "math: remainder must be smaller than the mod");
2450 crt = crt * detail::crt(rems[i], mods[i]);
2453 throw detail::there_is_no_in_range_error(
"congruent number", left,
2455 if (crt.m > right) {
2456 if (!(left <= crt.a
and crt.a <= right))
2457 throw detail::there_is_no_in_range_error(
"congruent number",
2460 for (
int j = 0; j <
static_cast<
int>(rems.size()); ++j)
2461 if (crt.a % mods[j] != rems[j])
2462 throw detail::there_is_no_in_range_error(
"congruent number",
2468 uint64_t k_min = crt.a >= left ? 0 : ((left - crt.a) + crt.m - 1) / crt.m;
2469 uint64_t k_max = (right - crt.a) / crt.m;
2472 throw detail::there_is_no_in_range_error(
"congruent number", left,
2475 return crt.a + next(k_min, k_max) * crt.m;
2482 return gen_congruent(left, right, std::vector<uint64_t>({rem}),
2483 std::vector<uint64_t>({mod}));
2491 std::vector<uint64_t> mods) {
2493 "math: number of remainders and mods must be the same");
2494 tgen_ensure(rems.size() > 0,
"math: must have at least one congruence");
2497 for (
int i = 0; i <
static_cast<
int>(rems.size()); ++i) {
2499 "math: remainder must be smaller than the mod");
2500 crt = crt * detail::crt(rems[i], mods[i]);
2503 throw detail::there_is_no_from_error(
"congruent number", left);
2504 if (crt.m > std::numeric_limits<uint64_t>::max()) {
2506 throw detail::error(
2507 "math: congruent number does not exist or is too large");
2509 for (
int j = 0; j <
static_cast<
int>(rems.size()); ++j)
2510 if (crt.a % mods[j] != rems[j])
2511 throw detail::error(
"math: congruent number does "
2512 "not exist or is too large");
2519 k = ((left - crt.a) + crt.m - 1) / crt.m;
2520 detail::i128 result = crt.a + k * crt.m;
2522 if (result > std::numeric_limits<uint64_t>::max())
2523 throw detail::error(
"math: congruent number is too large");
2524 return static_cast<uint64_t>(result);
2530 return congruent_from(left, std::vector<uint64_t>{rem},
2531 std::vector<uint64_t>{mod});
2539 std::vector<uint64_t> mods) {
2541 "math: number of remainders and mods must be the same");
2542 tgen_ensure(rems.size() > 0,
"math: must have at least one congruence");
2545 for (
int i = 0; i <
static_cast<
int>(rems.size()); ++i) {
2547 "math: remainder must be smaller than the mod");
2549 crt = crt * detail::crt(rems[i], mods[i]);
2552 throw detail::there_is_no_upto_error(
"congruent number", right);
2553 if (crt.m > right) {
2554 if (!(crt.a <= right))
2555 throw detail::there_is_no_upto_error(
"congruent number", right);
2557 for (
int j = 0; j <
static_cast<
int>(rems.size()); ++j)
2558 if (crt.a % mods[j] != rems[j])
2559 throw detail::there_is_no_upto_error(
"congruent number",
2566 throw detail::there_is_no_upto_error(
"congruent number", right);
2568 uint64_t k = (right - crt.a) / crt.m;
2569 detail::i128 result = crt.a + k * crt.m;
2572 throw detail::there_is_no_upto_error(
"congruent number", right);
2573 return static_cast<uint64_t>(result);
2579 return congruent_upto(right, std::vector<uint64_t>{rem},
2580 std::vector<uint64_t>{mod});
2588 static const std::vector<uint64_t> fib = [] {
2589 std::vector<uint64_t> v = {0, 1};
2591 std::numeric_limits<uint64_t>::max() - v[v.size() - 2])
2592 v.push_back(v.back() + v[v.size() - 2]);
2604 std::optional<
int> part_right = std::nullopt) {
2607 part_right = std::min(*part_right, n);
2609 "math: invalid parameters to gen_partition");
2610 tgen_ensure(part_left <= n
and *part_right > 0,
"math: no such partition");
2613 std::vector<
long double> dp(n + 1, detail::LOG_ZERO);
2614 dp[0] = detail::LOG_ONE;
2615 long double window = detail::LOG_ZERO;
2616 for (
int i = 1; i <= n; ++i) {
2618 window = detail::add_log_space(window, dp[i - part_left]);
2619 if (i >= *part_right + 1)
2620 window = detail::sub_log_space(window, dp[i - *part_right - 1]);
2623 tgen_ensure(dp[n] >= 0,
"math: no such partition");
2627 for (
int i = 1; i <= n; ++i)
2628 dp_pref[i] = detail::add_log_space(dp_pref[i - 1], dp[i]);
2630 std::vector<
int> part;
2634 int l = std::max(0, sum - *part_right), r = sum - part_left;
2635 detail::tgen_ensure_against_bug(r >= 0,
"math: r < 0 in gen_partition");
2637 int nxt_sum = std::min(sum, r);
2638 long double random = next<
long double>(0, 1);
2649 long double val_l = l ? dp_pref[l - 1] : detail::LOG_ZERO,
2651 while (nxt_sum > l
and
2652 dp_pref[nxt_sum - 1] >=
2653 val_r + detail::log_space(random +
2654 (1 - random) * exp(val_l - val_r)))
2657 part.push_back(sum - nxt_sum);
2670 std::optional<
int> part_right = std::nullopt) {
2673 part_right = std::min(*part_right, n);
2675 "math: invalid parameters to gen_partition_fixed_size");
2676 tgen_ensure(
static_cast<
long long>(k) * part_left <= n
and
2677 n <=
static_cast<
long long>(k) * (*part_right),
2678 "math: no such partition");
2681 int s = n - k * part_left;
2683 std::vector<
int> part(k);
2684 if (*part_right == n) {
2686 std::vector<
int> cuts = {-1};
2688 int total = s + k - 1, bars = k - 1;
2689 for (
int i = 0; i < total
and bars > 0; ++i)
2690 if (next<
long double>(0, 1) <
2691 static_cast<
long double>(bars) / (total - i)) {
2695 cuts.push_back(total);
2698 for (
int i = 0; i < k; ++i)
2699 part[i] = cuts[i + 1] - cuts[i] - 1;
2702 int u = *part_right - part_left;
2705 std::vector<std::vector<
long double>> dp(
2706 k + 1, std::vector<
long double>(s + 1, detail::LOG_ZERO));
2707 dp[0][0] = detail::LOG_ONE;
2709 for (
int i = 1; i <= k; ++i) {
2710 std::vector<
long double> pref = dp[i - 1];
2711 for (
int j = 1; j <= s; ++j)
2712 pref[j] = detail::add_log_space(pref[j - 1], dp[i - 1][j]);
2714 for (
int j = 0; j <= s; ++j) {
2717 dp[i][j] = detail::sub_log_space(dp[i][j], pref[j - u - 1]);
2722 int left_to_distribute = s;
2723 for (
int i = k; i >= 1; --i) {
2724 long double log_total = detail::LOG_ZERO;
2725 for (
int j = 0; j <= u
and j <= left_to_distribute; ++j)
2726 log_total = detail::add_log_space(
2727 log_total, dp[i - 1][left_to_distribute - j]);
2728 detail::tgen_ensure_against_bug(
2729 log_total != detail::LOG_ZERO,
2730 "math: total == 0 in gen_partition_fixed_size");
2736 long double random =
2737 detail::log_space(next<
long double>(0, 1)) + log_total;
2739 long double cur_prob = detail::LOG_ZERO;
2741 for (
int j = 0; j <= u
and j <= left_to_distribute; ++j) {
2742 cur_prob = detail::add_log_space(
2743 cur_prob, dp[i - 1][left_to_distribute - j]);
2744 if (random < cur_prob) {
2750 part[k - i] = chosen;
2751 left_to_distribute -= chosen;
2763
2764
2765
2766
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2809 std::vector<regex_node> children_;
2810 int left_bound_, right_bound_;
2813 log_space_num_ways_;
2818 regex_node(
const std::string &pattern)
2819 : pattern_(pattern), left_bound_(-1), right_bound_(-1) {
2820 if (pattern.size() == 1) {
2821 log_space_num_ways_ = math::detail::LOG_ONE;
2824 tgen_ensure_against_bug(pattern[0] ==
'[' and pattern.back() ==
']',
2825 "str: invalid regex: expected character class");
2826 int size = pattern.size() - 2;
2827 log_space_num_ways_ = math::detail::log_space(size);
2828 distinct_ = distinct_container<
char>(pattern.substr(1, size));
2831 regex_node(
const std::string &pattern, std::vector<regex_node> &children)
2832 : pattern_(pattern), left_bound_(-1), right_bound_(-1) {
2833 if (pattern ==
"SEQ") {
2835 log_space_num_ways_ = math::detail::LOG_ONE;
2836 for (
const auto &child : children)
2837 log_space_num_ways_ += child.log_space_num_ways_;
2838 }
else if (pattern ==
"OR") {
2840 log_space_num_ways_ = math::detail::LOG_ZERO;
2841 for (
const auto &child : children)
2842 log_space_num_ways_ = math::detail::add_log_space(
2843 log_space_num_ways_, child.log_space_num_ways_);
2845 tgen_ensure_against_bug(
"str: invalid regex: expected SEQ or OR");
2847 children_ = std::move(children);
2851 regex_node(
int left_bound,
int right_bound, regex_node &child)
2852 : pattern_(
"REP"), left_bound_(left_bound), right_bound_(right_bound) {
2853 log_space_num_ways_ = math::detail::LOG_ZERO;
2854 for (
int i = left_bound; i <= right_bound; ++i)
2855 log_space_num_ways_ = math::detail::add_log_space(
2856 log_space_num_ways_, i * child.log_space_num_ways_);
2858 children_.push_back(std::move(child));
2864 std::vector<regex_node> cur;
2865 std::vector<regex_node> branches;
2869inline regex_node make_regex_seq(regex_state &st) {
2870 return regex_node(
"SEQ", st.cur);
2874inline regex_node finish_regex_state(regex_state &st) {
2876 if (st.branches.empty())
2877 return make_regex_seq(st);
2880 st.branches.push_back(make_regex_seq(st));
2881 return regex_node(
"OR", st.branches);
2886inline regex_node parse_regex(std::string regex) {
2887 std::string new_regex;
2888 for (
char c : regex)
2891 swap(regex, new_regex);
2893 std::vector<regex_state> stack;
2895 for (size_t i = 0; i < regex.size(); ++i) {
2900 stack.push_back(std::move(cur));
2901 cur = regex_state();
2902 }
else if (c ==
')') {
2904 regex_node node = finish_regex_state(cur);
2906 tgen_ensure(!stack.empty(),
"str: invalid regex: unmatched `)`");
2907 cur = std::move(stack.back());
2910 cur.cur.push_back(std::move(node));
2911 }
else if (c ==
'|') {
2913 regex_node node = make_regex_seq(cur);
2914 cur.branches.push_back(std::move(node));
2915 }
else if (c ==
'[') {
2919 for (++i; i < regex.size()
and regex[i] !=
']'; ++i) {
2920 if (i + 2 < regex.size()
and regex[i + 1] ==
'-') {
2921 char a = regex[i], b = regex[i + 2];
2924 for (
char x = a; x <= b; ++x)
2932 "str: invalid regex: unmatched `[`");
2933 cur.cur.emplace_back(
"[" + chars +
"]");
2934 }
else if (c ==
'{') {
2939 while (i < regex.size()
and
2940 isdigit(
static_cast<
unsigned char>(regex[i]))) {
2944 "str: invalid regex: number too large inside `{}`");
2945 l = 10 * l + (regex[i] -
'0');
2949 if (i < regex.size()
and regex[i] ==
',') {
2951 while (i < regex.size()
and
2952 isdigit(
static_cast<
unsigned char>(regex[i]))) {
2956 r <=
static_cast<
int>(1e8),
2957 "str: invalid regex: number too large inside `{}`");
2958 r = 10 * r + (regex[i] -
'0');
2965 "str: invalid regex: unmatched `{`");
2967 "str: invalid regex: missing number inside `{}`");
2968 tgen_ensure(l <= r,
"invalid regex: invalid range inside `{}`");
2972 "str: invalid regex: expected expression before `{}`");
2974 regex_node rep(l, r, cur.cur.back());
2976 cur.cur.push_back(std::move(rep));
2979 cur.cur.emplace_back(std::string(1, c));
2983 tgen_ensure(stack.empty(),
"str: invalid regex: unmatched `(`");
2984 return finish_regex_state(cur);
2988inline void gen_regex(
const regex_node &node, std::string &str) {
2990 if (node.pattern_[0] ==
'[') {
2991 str += node.pattern_[1 + next<
int>(0, node.pattern_.size() - 3)];
2996 if (node.left_bound_ != -1) {
3000 double log_rand = math::detail::log_space(next<
double>(0, 1)) +
3001 node.log_space_num_ways_;
3002 double cur_prob = math::detail::LOG_ZERO;
3003 double child_num_ways = node.children_[0].log_space_num_ways_;
3005 for (
int i = node.left_bound_; i <= node.right_bound_; ++i) {
3007 math::detail::add_log_space(cur_prob, i * child_num_ways);
3008 if (log_rand <= cur_prob) {
3009 for (
int j = 0; j < i; ++j)
3010 gen_regex(node.children_[0], str);
3015 tgen_ensure_against_bug(
false,
3016 "str: log_rand > cur_prob in REP gen_regex");
3020 if (!node.children_.empty()
and node.pattern_ ==
"SEQ") {
3021 for (
const regex_node &child : node.children_)
3022 gen_regex(child, str);
3027 if (!node.children_.empty()
and node.pattern_ ==
"OR") {
3031 double log_rand = math::detail::log_space(next<
double>(0, 1)) +
3032 node.log_space_num_ways_;
3033 double cur_prob = math::detail::LOG_ZERO;
3035 for (
const regex_node &child : node.children_) {
3036 cur_prob = math::detail::add_log_space(cur_prob,
3037 child.log_space_num_ways_);
3038 if (log_rand <= cur_prob) {
3039 gen_regex(child, str);
3044 tgen_ensure_against_bug(
false,
3045 "str: log_rand > cur_prob in OR gen_regex");
3049 detail::tgen_ensure_against_bug(
3050 node.pattern_.size() == 1,
3051 "str: invalid regex: expected single character, but got `" +
3052 node.pattern_ +
"`");
3053 str += node.pattern_[0];
3057template <
typename... Args>
3058std::string regex_format(
const std::string &s, Args &&...args) {
3059 if constexpr (
sizeof...(Args) == 0) {
3062 int size = std::snprintf(
nullptr, 0, s.c_str(), args...) + 1;
3063 std::string buf(size,
'\0');
3064 std::snprintf(buf.data(), size, s.c_str(), args...);
3073
3074
3077 std::optional<
list<
char>> list_;
3078 std::optional<detail::regex_node>
3083 str(
int size,
char value_left =
'a',
char value_right =
'z')
3091 template <
typename... Args>
str(
const std::string ®ex, Args &&...args) {
3092 tgen_ensure(regex.size() > 0,
"str: regex must be non-empty");
3094 root_ = detail::parse_regex(
3095 detail::regex_format(regex, std::forward<Args>(args)...));
3100 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3101 list_->fix(idx, character);
3107 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3108 list_->equal(indices);
3114 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3115 list_->equal(idx_1, idx_2);
3121 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3122 list_->equal_range(left, right);
3128 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3135 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3136 tgen_ensure(0 <= left
and left <= right
and right < list_->size_,
3137 "str: range indices must be valid");
3138 for (
int i = left; i < right - (i - left); ++i)
3145 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3146 return palindrome(0, list_->size_ - 1);
3152 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3153 list_->different(indices);
3159 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3160 list_->different(idx_1, idx_2);
3166 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3167 list_->different_range(left, right);
3173 tgen_ensure(!root_,
"str: cannot add restriction for regex");
3174 list_->all_different();
3180 using tgen_is_sequential_tag = detail::is_sequential_tag;
3181 using tgen_has_subset_defined_tag = detail::has_subset_defined_tag;
3183 using value_type =
char;
3184 using std_type = std::string;
3187 value(
const std::string &str) : str_(str) {
3188 tgen_ensure(!str_.empty(),
"str: value: cannot be empty");
3192 int size()
const {
return str_.size(); }
3197 "str: instane: index out of bounds");
3200 const char &operator[](
int idx)
const {
3202 "str: value: index out of bounds");
3209 std::sort(str_.begin(), str_.end());
3216 std::reverse(str_.begin(), str_.end());
3223 for (
char &c : str_)
3224 c = std::tolower(c);
3231 for (
char &c : str_)
3232 c = std::toupper(c);
3241 friend std::ostream &operator<<(std::ostream &out,
const value &inst) {
3242 return out << inst.str_;
3255 std::string ret_str;
3256 gen_regex(*root_, ret_str);
3260 std::vector<
char> vec = list_->gen().to_std();
3261 return value(std::string(vec.begin(), vec.end()));
3267
3268
3269
3270
3276template <
typename T> std::pair<T, T> gen_eq(T L1, T R1, T L2, T R2) {
3277 T L = std::max(L1, L2);
3278 T R = std::min(R1, R2);
3280 tgen_ensure(L <= R,
"pair: no valid values to generate");
3281 T x = next<T>(L, R);
3286template <
typename T>
3287std::pair<u128, u128> get_n_and_m(T L1, T R1, T L2, T R2) {
3288 u128 n =
static_cast<i128>(R1) - L1 + 1;
3289 u128 m =
static_cast<i128>(R2) - L2 + 1;
3295static u128 pos_arith_sum(u128 first, u128 last, u128 num_terms) {
3296 u128 x = first + last, y = num_terms;
3309template <
typename T> std::pair<T, T> gen_neq(T L1, T R1, T L2, T R2) {
3310 auto [n, m] = get_n_and_m(L1, R1, L2, R2);
3312 T L_intersect = std::max(L1, L2);
3313 T R_intersect = std::min(R1, R2);
3314 u128 inter =
static_cast<i128>(R_intersect) - L_intersect + 1;
3316 u128 total = n * m - inter;
3317 tgen_ensure(total > 0,
"pair: no valid values to generate");
3322 a = next<T>(L1, R1);
3323 b = next<T>(L2, R2);
3334template <
typename T>
3335std::pair<u128, u128> count_lt_regions(T L1, T R1, T L2, T R2) {
3336 auto [n, m] = get_n_and_m(L1, R1, L2, R2);
3339 i128 L_second = std::max<i128>(L2,
static_cast<i128>(L1) + 1);
3343 i128 split = std::min<i128>(R_second, R1);
3346 u128 len1 = std::max<i128>(0, split - L_second + 1);
3348 u128 count_region1 = 0;
3351 i128 first = L_second - L1;
3352 i128 last = split - L1;
3355 count_region1 = pos_arith_sum(first, last, len1);
3360 i128 L_second_region2 = std::max(L_second,
static_cast<i128>(R1) + 1);
3362 u128 len2 = std::max<i128>(0, R_second - L_second_region2 + 1);
3363 u128 count_region2 = len2 * n;
3365 return {count_region1, count_region2};
3370template <
typename T> std::pair<T, T> gen_lt(T L1, T R1, T L2, T R2) {
3371 auto [n, m] = get_n_and_m(L1, R1, L2, R2);
3375 i128 L_second = std::max<i128>(L2,
static_cast<i128>(L1) + 1);
3381 i128 split = std::min<i128>(R_second, R1);
3383 auto [count_region1, count_region2] = count_lt_regions(L1, R1, L2, R2);
3384 u128 total = count_region1 + count_region2;
3385 tgen_ensure(total > 0,
"pair: no valid values to generate");
3387 u128 k = detail::next128(total);
3388 if (k < count_region1) {
3392 u128 len1 = std::max<i128>(0, split - L_second + 1);
3399 i128 base = L_second - L1;
3400 i128 lo = 0, hi =
static_cast<i128>(len1) - 1;
3403 i128 mid = lo + (hi - lo) / 2;
3405 if (pos_arith_sum(base, base + mid, mid + 1) <= k)
3414 k -= pos_arith_sum(base, base + d - 1, d);
3416 return {L1 +
static_cast<T>(k), L_second + d};
3422 i128 L_second_region2 = std::max(L_second,
static_cast<i128>(R1) + 1);
3424 return {L1 +
static_cast<T>(k % n),
3425 L_second_region2 +
static_cast<T>(k / n)};
3431template <
typename T> std::pair<T, T> gen_gt(T L1, T R1, T L2, T R2) {
3432 auto [first, second] = gen_lt(L2, R2, L1, R1);
3433 return {second, first};
3438template <
typename T> std::pair<T, T> gen_leq(T L1, T R1, T L2, T R2) {
3440 i128 L_intersect = std::max(L1, L2);
3441 i128 R_intersect = std::min(R1, R2);
3442 u128 eq_count = std::max<i128>(0, R_intersect - L_intersect + 1);
3445 auto [lt_region1, lt_region2] = count_lt_regions(L1, R1, L2, R2);
3446 u128 lt_count = lt_region1 + lt_region2;
3448 u128 total = eq_count + lt_count;
3449 tgen_ensure(total > 0,
"pair: no valid values to generate");
3451 if (detail::next128(total) < eq_count)
3452 return gen_eq(L1, R1, L2, R2);
3453 return gen_lt(L1, R1, L2, R2);
3458template <
typename T> std::pair<T, T> gen_geq(T L1, T R1, T L2, T R2) {
3459 auto [first, second] = gen_leq(L2, R2, L1, R1);
3460 return {second, first};
3466
3467
3468
3469
3472 std::pair<T, T> first_, second_;
3474 enum class restriction_type { eq, neq, lt, gt, leq, geq, unspecified };
3475 restriction_type type_ = restriction_type::unspecified;
3479 pair(T first_left, T first_right, T second_left, T second_right)
3480 : first_(first_left, first_right), second_(second_left, second_right) {
3482 "pair: first range must be valid");
3484 "pair: second range must be valid");
3489 :
pair(both_left, both_right, both_left, both_right) {}
3493 type_ = restriction_type::eq;
3499 type_ = restriction_type::neq;
3505 type_ = restriction_type::lt;
3511 type_ = restriction_type::gt;
3517 type_ = restriction_type::leq;
3523 type_ = restriction_type::geq;
3529 using value_type = T;
3530 using std_type = std::pair<T, T>;
3532 std::pair<T, T> pair_;
3535 value(
const std::pair<T, T> &pair) : pair_(pair), sep_(
' ') {}
3537 : pair_(first, second), sep_(
' ') {}
3549 friend std::ostream &operator<<(std::ostream &out,
const value &inst) {
3550 return out << inst.pair_.first << inst.sep_ << inst.pair_.second;
3558 std::pair<
typename T::std_type,
typename T::std_type> pair(
3559 pair_.first.to_std(), pair_.second.to_std());
3568 T L1 = first_.first, R1 = first_.second;
3569 T L2 = second_.first, R2 = second_.second;
3572 case restriction_type::unspecified:
3573 return {next<T>(L1, R1), next<T>(L2, R2)};
3574 case restriction_type::eq:
3575 return detail::gen_eq<T>(L1, R1, L2, R2);
3576 case restriction_type::neq:
3577 return detail::gen_neq<T>(L1, R1, L2, R2);
3578 case restriction_type::lt:
3579 return detail::gen_lt<T>(L1, R1, L2, R2);
3580 case restriction_type::gt:
3581 return detail::gen_gt<T>(L1, R1, L2, R2);
3582 case restriction_type::leq:
3583 return detail::gen_leq<T>(L1, R1, L2, R2);
3584 case restriction_type::geq:
3585 return detail::gen_geq<T>(L1, R1, L2, R2);
3587 throw detail::error(
"pair: unknown restriction type");
3592
3593
3594
3595
3597
3598
3599
3600
3601
3602
3603
3605template <
typename VWeight =
int,
typename EWeight =
int>
3608 std::set<std::pair<
int,
int>> edg_;
3610 bool has_self_loops_;
3612 graph(
int n,
int m,
bool is_directed =
false,
bool has_self_loops =
false)
3613 : n_(n), m_(m), is_directed_(is_directed),
3614 has_self_loops_(has_self_loops) {}
3616 graph &add_edge(
int u,
int v) {
3617 tgen_ensure(0 <= u
and u < n_,
"vertex index must be valid");
3618 tgen_ensure(0 <= v
and v < n_,
"vertex index must be valid");
3620 if (!is_directed_
and u > v)
3629 std::vector<std::set<
int>> adj_;
3636 value(
int n,
int m,
const std::set<std::pair<
int,
int>> &edges = {})
3637 : n_(n), m_(m), adj_(n_), add_1_(
false), print_nm_(
false),
3639 for (
auto [u, v] : edges) {
3640 tgen_ensure(0 <= u
and u < n,
"graph: value: invalid edge");
3641 tgen_ensure(0 <= v
and v < n,
"graph: value: invalid edge");
3646 int n()
const {
return n_; }
3648 int m()
const {
return m_; }
3650 const std::vector<std::set<
int>> &adj()
const {
return adj_; }
3668 friend std::ostream &operator<<(std::ostream &out,
const value &inst) {
3670 out << inst.n() <<
" " << inst.m() << std::endl;
3672 std::vector<
int> print_label(inst.n());
3673 std::iota(print_label.begin(), print_label.end(), 0);
3675 tgen::shuffle(print_label.begin(), print_label.end());
3677 std::vector<std::pair<
int,
int>> edges;
3678 for (
int u = 0; u < inst.n(); ++u)
3679 for (
int v : inst.adj()[u])
3680 edges.emplace_back(u, v);
3682 tgen::shuffle(edges.begin(), edges.end());
3684 detail::tgen_ensure_against_bug(edges.size() == inst.m(),
3685 "graph: invalid number of edges");
3687 for (
auto [u, v] : edges)
3688 out << (print_label[u] + inst.add_1_) <<
" "
3689 << (print_label[v] + inst.add_1_) << std::endl;
3695 std::tuple<
int,
int, std::vector<std::set<
int>>> to_std() {
3696 return std::tuple(n_, m_, adj_);
3701 tgen::
pair gen_repeat(0, n_ - 1);
3702 if (has_self_loops_) {
3711 auto edge_gen = gen_repeat.distinct();
3714 tgen_ensure(edges.size() <= m_,
"too many edges were added");
3716 while (edges.size() < m_) {
3718 edges.insert(edge_gen.gen().to_std());
3719 }
catch (std::runtime_error &e) {
3720 throw detail::error(
3721 std::string(
"graph: probably enough edges to generate: ") +
3726 return value(n_, m_, edges);
3729 static value k(
int n) {
return graph(n, n * (n - 1) / 2).gen(); }
3733
3734
3735
3736
3742using namespace tgen::detail;
3746inline int hash_string(
const std::string &s,
int base,
int mod) {
3749 h = (h * base + c -
'a' + 1) % mod;
3754inline int estimate_length(
int alphabet_size,
int mod) {
3756 double base_len = 2.5 * std::log(std::sqrt(
static_cast<
double>(mod)));
3757 double scale = std::log(
static_cast<
double>(alphabet_size)) / std::log(2.0);
3758 double adjusted = base_len / std::max(1.0, scale * 0.7);
3760 return static_cast<
int>(std::ceil(adjusted));
3765inline std::pair<std::string, std::string>
3766birthday_attack(
const std::vector<std::string> &alphabet,
int base,
int mod) {
3768 "birthday_attack: base must be in (0, mod)");
3769 std::map<uint64_t, std::vector<
int>> seen;
3770 int length = estimate_length(alphabet.size(), mod);
3773 std::vector<
int> seq(length);
3776 s.reserve(length * alphabet[0].size());
3778 for (
int i = 0; i < length; ++i) {
3779 seq[i] = next<
int>(0, alphabet.size() - 1);
3780 s += alphabet[seq[i]];
3783 int h = hash_string(s, base, mod);
3785 auto it = seen.find(h);
3786 if (it != seen.end()
and it->second != seq) {
3789 for (
int x : it->second)
3804inline std::set<
long long> std_hash_multipliers() {
3805 std::set<
long long> multipliers = {85229};
3808 bool codeforces_gcc_case =
true;
3809 if (cpp.version_ != 0
and cpp.version_ != 17)
3810 codeforces_gcc_case =
false;
3811 if (compiler.kind_ != compiler_kind::unknown
and
3812 compiler.kind_ != compiler_kind::gcc)
3813 codeforces_gcc_case =
false;
3814 if (compiler.major_ > 7)
3815 codeforces_gcc_case =
false;
3817 if (codeforces_gcc_case)
3818 multipliers.insert(107897);
3829 std::string str =
"a";
3831 while (
static_cast<
int>(str.size()) < n) {
3832 int prev_size = str.size();
3834 for (
int j = 0; j < prev_size
and static_cast<
int>(str.size()) < n; ++j)
3847 for (
int i = 0; i < size; ++i) {
3848 a +=
'a' + math::detail::popcount(i) % 2;
3849 b +=
'a' + (
'b' - a[i]);
3857inline std::pair<std::string, std::string>
3859 tgen_ensure(alphabet_size > 1,
"str: alphabet size must be greater than 1");
3860 tgen_ensure(0 < base
and base < mod,
"str: base must be in (0, mod)");
3862 std::vector<std::string> alphabet(alphabet_size);
3863 for (
int i = 0; i < alphabet_size; ++i)
3864 alphabet[i] = std::string(1,
'a' + i);
3865 std::iota(alphabet.begin(), alphabet.end(),
'a');
3866 return detail::birthday_attack(alphabet, base, mod);
3873inline std::pair<std::string, std::string>
3875 std::vector<
int> mods) {
3877 "str: bases and mods must have the same size");
3879 "str: must have at least one (base, mod) pair");
3880 tgen_ensure(bases.size() <= 2,
"str: multi-hash hack only supported "
3881 "for up to 2 (base, mod) pairs");
3883 std::vector<std::string> alphabet(alphabet_size);
3884 for (
int i = 0; i < alphabet_size; ++i)
3885 alphabet[i] = std::string(1,
'a' + i);
3886 auto [S1, T1] = detail::birthday_attack(alphabet, bases[0], mods[0]);
3887 if (bases.size() == 1)
3889 return detail::birthday_attack({S1, T1}, bases[1], mods[1]);
3895 tgen_ensure(size > 0,
"misc: unordered_hack: size must be positive");
3896 std::set<
long long> multipliers = detail::std_hash_multipliers();
3898 std::set<
long long>::iterator it = multipliers.begin();
3900 std::vector<
long long> list;
3901 while (
static_cast<
int>(list.size()) < size) {
3902 list.push_back(mult * (*it));
3904 if (it == multipliers.end()) {
3905 it = multipliers.begin();
3922 std::set<std::pair<
int,
int>> queries;
3923 for (
int i = 0; i < n; ++i) {
3924 queries.emplace(0, i);
3925 queries.emplace(i, i);
3926 queries.emplace(i, n - 1);
3935 std::vector<std::string> list;
3936 int k = 0, left = size;
3938 int cur_size = std::min(left, k + 1);
3941 char right_char = cur_size == k + 1 ?
'b' :
'c';
3947 return tgen::shuffled(list);
3953
3954
3955
3956
3965 "misc: parenthesis: size must a positive even number");
3969 int open = 0, close = 0;
3971 for (
int i = 0; i < size; ++i) {
3977 if (open == close) {
3983 long long a = k - open, b = k - close, h = open - close;
3988 long long num = a * (h + 2);
3989 long long den = (a + b) * (h + 1);
3991 if (next<
long long>(1, den) <= num) {
C choose(const C &container, int k)
Chooses elements from container, as in a subsequence fixed length.
C::value_type pick(const C &container)
Choses a random element from container.
void shuffle(It first, It last)
Shuffles range inplace, for random_access_iterator.
It::value_type pick(It first, It last)
Choses a random element from iterator range.
T next(T right)
Returns a random number up to value.
auto shuffled(const C &container)
Shuffles a container.
size_t next_by_distribution(const std::vector< T > &distribution)
Returns random index with given probabilities.
C::value_type pick_by_distribution(const C &container, std::vector< T > distribution)
Choses a random element with given probabilities.
#define tgen_ensure(cond,...)
Ensures condition is true.
T next(T left, T right)
Returns a random number in range.
Inst shuffled(const Inst &inst)
Shuffles a list value.
void shuffle(Inst &inst)
Shuffles a list value.
Inst::value_type pick_by_distribution(const Inst &inst, const std::vector< T > &distribution)
Choses a random element from the list value.
std::pair< std::string, std::string > unsigned_polynomial_hash_hack()
Returns two strings that force polynomial hash collision for power-of-two mod.
std::vector< std::string > string_set(int size)
List of strings that have high cost to insert in a std::set.
std::string abacaba(int n)
Returns the prefix of the infinite word "abacabad...".
std::vector< long long > std_unordered(int size)
List of integers that tries to force collision on std::unordered_set.
std::pair< std::string, std::string > polynomial_hash_hack(int alphabet_size, int base, int mod)
Returns two strings that force polynomial hash collision given base and mod.
std::vector< std::pair< int, int > > mo(int n, int q)
Query list that tries to force asymptotic worst-case for Mo's algorithm.
uint64_t prime_from(uint64_t left)
Computes smallest prime from given value.
uint64_t gen_divisor_count(uint64_t left, uint64_t right, int divisor_count)
Generates random number in range with a given prime number of divisors.
std::vector< int > gen_partition_fixed_size(int n, int k, int part_left=0, std::optional< int > part_right=std::nullopt)
Generates a random partition with fixed size of a number.
uint64_t totient(uint64_t n)
Euler's totient function.
uint64_t congruent_from(uint64_t left, std::vector< uint64_t > rems, std::vector< uint64_t > mods)
Computes smallest congruent from given value.
uint64_t congruent_upto(uint64_t right, uint64_t rem, uint64_t mod)
Computes largest congruent up to given value.
uint64_t gen_prime(uint64_t left, uint64_t right)
Generates a random prime in given range.
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.
std::vector< int > gen_partition(int n, int part_left=1, std::optional< int > part_right=std::nullopt)
Generates a random partition of a number.
constexpr int FFT_MOD
FFT/NTT mod.
uint64_t gen_congruent(uint64_t left, uint64_t right, uint64_t rem, uint64_t mod)
Generates random number in range given a modular congruence.
uint64_t prime_upto(uint64_t right)
Computes largest prime up to given value.
uint64_t highly_composite_upto(uint64_t right)
Largest highly composite number up to given number.
uint64_t congruent_upto(uint64_t right, std::vector< uint64_t > rems, std::vector< uint64_t > mods)
Computes largest congruent up to given value.
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 congruent_from(uint64_t left, uint64_t rem, uint64_t mod)
Computes smallest congruent from given value.
const std::vector< uint64_t > & highly_composites()
Fetches highly composite numbers.
uint64_t gen_congruent(uint64_t left, uint64_t right, std::vector< uint64_t > rems, std::vector< uint64_t > mods)
Generates random number in range given modular congruences.
std::pair< uint64_t, uint64_t > prime_gap_upto(uint64_t right)
Largest prime gap up to given number.
std::string gen_parenthesis(int size)
Generates a random valid parenthesis sequence.
T opt(const std::string &key, std::optional< T > default_value=std::nullopt)
Gets opt by key.
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.
Distinct generator for containers.
auto gen_list(int size)
Generates a list of several distinct elements.
T gen()
Generates a distinct random element from the container.
distinct_container(const C &container)
Creates distinct generator for elements of the given container.
auto gen_all()
Generates all distinct elements left to generate.
size_t size() const
Returns the number of elements left to generate.
Distinct generator for integral ranges.
auto gen_all()
Generates all distinct values left to generate.
T gen()
Generates a distinct random value in the defined range.
auto gen_list(int size)
Generates a list of several distinct values.
distinct_range(T l, T r)
Creates distinct generator for values in given range.
T size() const
Returns the number of values left to generate.
Distinct generator for discrete uniform functions.
distinct(Func func, Args... args)
Generates a distinct generator of a discrete uniform function.
auto gen_list(int size)
Generates a list of several distinct values.
bool empty()
Checks if there is nothing left to generate.
auto gen_all()
Generates all distinct values left to generate.
auto gen()
Generates a distinct value.
Base class for generators (should not be instantiated).
auto gen_list(int size, Args &&...args) const
Generates a list of several generation calls.
auto gen_until(Pred predicate, int max_tries, Args &&...args) const
Generates a random value from the valid set until a condition is met.
auto distinct(Args &&...args) const
Creates distinct generator for current generator.
Base class for generator values (should not be instantiated).
bool operator<(const Inst &rhs) const
If type is defined for a subset of itself, for tgen generator value.
If type is associative container.
If type is a tgen generator value.
If type is a list-like tgen generator value.
int size() const
Returns the size of the list value.
value(const std::vector< T > &vec)
Creates a list value from a std::vector.
value & sort()
Sorts the value in non-decreasing order.
auto to_std() const
Converts the value to a std::vector.
value operator+(const value &rhs)
Concatenates two values.
value & separator(char sep)
Sets separator for printing.
T & operator[](int idx)
Accesses the value at some position of the value.
value & reverse()
Reverses the value.
list & different(int idx_1, int idx_2)
Restricts generator s.t. values at two indices are different.
list & equal(int idx_1, int idx_2)
Restricts generator s.t. values at two indices are equal.
list & all_different()
Restricts generator s.t. all values are different.
list & equal_range(int left, int right)
Restricts generator s.t. all values at index range are equal.
list(int size, std::set< T > values)
Creates list generator defined by value set.
value gen() const
Generates a random value from the set of valid lists.
list & all_equal()
Restricts generator s.t. all values are equal.
list & different(std::set< int > indices)
Restricts generator s.t. all values in index set are different.
list & different_range(int left, int right)
Restricts generator s.t. all values at index range are different.
list(int size, T value_left, T value_right)
Creates list generator defined by size and range of values.
list & fix(int idx, T val)
Restricts generator s.t. value at index is fixed.
list & equal(std::set< int > indices)
Restricts generator s.t. all values in index set are equal.
T second() const
Returns the second element of a pair value.
value(const T &first, const T &second)
Creates a pair value from first and second values.
value(const std::pair< T, T > &pair)
Creates a pair value from a std::pair.
auto to_std() const
Converts the value to a std::pair.
T first() const
Returns the first element of a pair value.
value & separator(char sep)
Sets separator for printing.
value gen() const
Generates a random value from the set of valid pairs.
pair & neq()
Restricts generator s.t. first is not equal to second.
pair & leq()
Restricts generator s.t. first is less than or equal to second.
pair & lt()
Restricts generator s.t. first is less than second.
pair & gt()
Restricts generator s.t. first is greater than second.
pair(T both_left, T both_right)
Creates pair generator defined by range of values for both first and second.
pair & eq()
Restricts generator s.t. first is equal to second.
pair(T first_left, T first_right, T second_left, T second_right)
Creates pair generator defined by range of values for first and second.
pair & geq()
Restricts generator s.t. first is greater than or equal to second.
value & add_1()
Adds 1 for printing.
std::vector< int > to_std() const
Converts the value to a std::vector.
const int & operator[](int idx) const
Returns the value at some position of the value.
value & sort()
Sorts the value in non-decreasing order.
int parity() const
Parity of the permutation.
value & reverse()
Reverses the value.
value(const std::vector< int > &vec)
Creates a permutation value from a std::vector.
int size() const
Returns the size of the permutation value.
value & inverse()
Inverse of the permutation.
value & separator(char sep)
Sets separator for printing.
value gen() const
Generates a random value from the set of valid permutations.
permutation & cycles(const std::vector< int > &cycle_sizes)
Restricts generator s.t. cycle sizes are fixed.
permutation(int size)
Creates permutation generator defined by size.
permutation & fix(int idx, int val)
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.
value & lowercase()
Sets all characters to lowercase.
value & reverse()
Reverses the value.
int size() const
Returns the size of the string value.
value operator+(const value &rhs)
Concatenates two values.
value(const std::string &str)
Creates a string value from a std::string.
char & operator[](int idx)
Accesses the character at some position of the value.
value & uppercase()
Sets all characters to uppercase.
std::string to_std() const
Converts the value to a std::string.
value & sort()
Sorts the characters in non-decreasing order.
str & different(int idx_1, int idx_2)
Restricts generator s.t. characters at two indices are different.
str & palindrome(int left, int right)
Restricts generator s.t. range is a palindrome.
value gen() const
Generates a random value from the set of valid strings.
str(int size, char value_left='a', char value_right='z')
Creates string generator defined by size and range of characters.
str & different(std::set< int > indices)
Restricts generator s.t. all characters in index set are different.
str(const std::string ®ex, Args &&...args)
Creates string generator defined by regex.
str & equal(int idx_1, int idx_2)
Restricts generator s.t. characters at two indices are equal.
str & equal(std::set< int > indices)
Restricts generator s.t. all characters in index set are equal.
str & equal_range(int left, int right)
Restricts generator s.t. all characters at index range are equal.
str & fix(int idx, char character)
Restricts generator s.t. character at index is fixed.
str & all_equal()
Restricts generator s.t. all values are equal.
str & different_range(int left, int right)
Restricts generator s.t. all characters at index range are different.
str & palindrome()
Restricts generator s.t. string is a palindrome.
str & all_different()
Restricts generator s.t. all characters are different.
str(int size, std::set< char > chars)
Creates string generator defined by character set.