tgen
Loading...
Searching...
No Matches
tgen.h
1/*
2 * Copyright (c) 2026 Bruno Monteiro
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#pragma once
24
25#include <algorithm>
26#include <any>
27#include <functional>
28#include <iostream>
29#include <map>
30#include <optional>
31#include <queue>
32#include <random>
33#include <set>
34#include <sstream>
35#include <stack>
36#include <stdexcept>
37#include <string>
38#include <type_traits>
39#include <typeindex>
40#include <vector>
41
42namespace tgen {
43
44/**************************
45 * *
46 * GENERAL OPERATIONS *
47 * *
48 **************************/
49
50namespace _detail {
51
52/*
53 * Error handling.
54 */
55
56inline void throw_assertion_error(const std::string &condition,
57 const std::string &msg) {
58 throw std::runtime_error("tgen: " + msg + " (assertion `" + condition +
59 "` failed)");
60}
61inline void throw_assertion_error(const std::string &condition) {
62 throw std::runtime_error("tgen: assertion `" + condition + "` failed");
63}
64inline std::runtime_error error(const std::string &msg) {
65 return std::runtime_error("tgen: " + msg);
66}
67inline std::runtime_error contradiction_error(const std::string &type,
68 const std::string &msg = "") {
69 // Tried to generate a contradicting type.
70 std::string error_msg =
71 type + ": invalid " + type + " (contradicting restrictions)";
72 if (!msg.empty())
73 error_msg += ": " + msg;
74 return error(error_msg);
75}
76inline std::runtime_error
77complex_restrictions_error(const std::string &type,
78 const std::string &msg = "") {
79 // Tried to generate a type with too many distinct restrictions.
80 std::string error_msg =
81 type + ": cannot represent " + type + " (complex restrictions)";
82 if (!msg.empty())
83 error_msg += ": " + msg;
84 return error(error_msg);
85}
86inline void tgen_ensure_against_bug(bool cond, const std::string &msg = "") {
87 if (!cond) {
88 std::cerr << "tgen: " << msg << std::endl;
89 throw std::runtime_error(
90 "tgen: THERE IS A BUG IN TGEN; PLEASE CONTACT MAINTAINERS");
91 }
92}
93
94// Ensures condition is true, with nice debug.
95#define tgen_ensure(cond, ...)
96 if (!(cond))
97 tgen::_detail::throw_assertion_error(#cond, ##__VA_ARGS__);
98
99// Registering checks.
100inline bool registered = false;
101inline void ensure_registered() {
102 tgen_ensure(registered,
103 "tgen was not registered! You should call "
104 "tgen::register_gen(argc, argv) before running tgen functions");
105}
106
107// Template magic to detect types in compile time.
108
109// Detects containers != std::string.
110template <typename T, typename = void> struct is_container : std::false_type {};
111template <typename T>
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>()))>>
116 : std::true_type {};
117// Exclude all basic_string variants
118template <typename Char, typename Traits, typename Alloc>
119struct is_container<std::basic_string<Char, Traits, Alloc>> : std::false_type {
120};
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 {};
130
131// Detects std::pair.
132template <typename T> struct is_pair : std::false_type {};
133template <typename A, typename B>
134struct is_pair<std::pair<A, B>> : std::true_type {};
135// Detects std::tuple.
136template <typename T> struct is_tuple : std::false_type {};
137template <typename... Ts>
138struct is_tuple<std::tuple<Ts...>> : std::true_type {};
139// Detects scalar (printed atomically).
140template <typename T>
143 !is_pair<T>::value> {};
144// Detects complex container.
145template <typename T>
151// Detects complex std::pair.
152template <typename T> struct is_pair_multiline : std::false_type {};
153template <typename A, typename B>
154struct is_pair_multiline<std::pair<A, B>>
156// Detects complex std::tuple.
157template <typename Tuple> struct is_tuple_multiline : std::false_type {};
158template <typename... Ts>
159struct is_tuple_multiline<std::tuple<Ts...>>
160 : std::bool_constant<(!is_scalar<Ts>::value or ...)> {};
161
162/*
163 * Properties of custom types.
164 */
165
166// If type is sequence-like.
167using is_sequential_tag = void;
168
169// If it makes sense to have a subset of the type.
170using has_subset_defined_tag = void;
171
172/*
173 * Unique rng to use.
174 */
175
176// The single rng to be used by the library.
177inline std::mt19937 rng;
178
179// Used to return false in compile time only if evaluated.
180template <typename> inline constexpr bool dependent_false_v = false;
181
182/*
183 * C++ version types.
184 */
185
186// Global C++ version value (0 means unknown).
187struct cpp_value {
188 int version_;
189
190 cpp_value(std::optional<int> version = std::nullopt)
191 : version_(version ? *version : 0) {
192 if (version) {
193 tgen_ensure(*version == 17 or *version == 20 or *version == 23,
194 "unsupported C++ version (use 17, 20, 23)");
195 }
196 }
197};
198inline cpp_value cpp;
199
200/*
201 * Compiler types.
202 */
203
204// Kinds of compilers.
205enum class compiler_kind { gcc, clang, unknown };
206
207// Global compiler value.
208struct compiler_value {
209 compiler_kind kind_;
210 int major_;
211 int minor_;
212
213 compiler_value(compiler_kind kind = compiler_kind::unknown, int major = 0,
214 int minor = 0)
215 : kind_(kind), major_(major), minor_(minor) {}
216};
217inline compiler_value compiler;
218
219} // namespace _detail
220
221/*
222 * Base classes.
223 */
224
225// Needed for return type of some functions.
226template <typename T> struct sequence;
227
228// Generates unique instances of a function.
229template <typename Func, typename... Args> struct unique {
230 Func func_;
231 std::tuple<Args...> args_;
232 using T = std::invoke_result_t<Func &, Args &...>;
233 std::set<T> seen_;
234
235 unique(Func func, Args... args)
236 : func_(std::move(func)), args_(std::move(args)...) {}
237
238 // Generates unique instance and inserts it if `insert` is true.
239 // Returns the instance if found, otherwise returns std::nullopt.
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);
245 }
246
247 // Not found.
248 return std::optional<T>();
249 }
250
251 // Generates a unique instance (i.e., one not returned before).
252 //
253 // Assume gen() produces a uniformly random instance in O(T) time.
254 // Since duplicates are rejected, the expected number of trials over
255 // k successful generations is:
256 //
257 // sum_{i=1}^k k / i = O(k log k)
258 //
259 // (coupon collector argument).
260 //
261 // Each trial additionally performs O(log k) work to check/store
262 // previously generated values, yielding a total time of
263 // O((T + log k) * k log k).
264 //
265 // Thus, the amortized expected time per call is
266 // O(T * log k + log^2 k).
267 //
268 // With extremely small probability (< 1e-18), the algorithm may
269 // incorrectly report that no more unique values exist.
270 auto gen() {
271 auto val = generate_unique(true);
272 if (val)
273 return *val;
274
275 throw _detail::error("no more unique values");
276 }
277 template <typename U> auto gen(std::initializer_list<U> il) {
278 return gen(std::vector<U>(il));
279 }
280
281 // Generates a list of unique instances.
282 auto gen_list(int size) {
283 std::vector<T> res;
284 for (int i = 0; i < size; ++i)
285 res.push_back(gen());
286
287 return typename sequence<T>::instance(res);
288 }
289
290 // Checks if there are no more unique instances.
291 // With extremely small probability (< 1e-18), the algorithm may
292 // incorrectly report that there are no more unique values.
293 bool empty() { return generate_unique(false) == std::nullopt; }
294
295 // Generates all unique instances.
296 auto gen_all() {
297 std::vector<T> res;
298 while (true) {
299 auto val = generate_unique(true);
300 if (val)
301 res.push_back(*val);
302 else
303 break;
304 }
305 return typename sequence<T>::instance(res);
306 }
307
308 // Nice error for `out << unique`.
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 "
312 "call `gen()`?");
313 return out;
314 }
315};
316template <typename Func, typename... Args>
317unique(Func, Args...) -> unique<Func, Args...>;
318
319// Base struct for generators.
320template <typename Gen> struct gen_base {
321 const Gen &self() const { return *static_cast<const Gen *>(this); }
322
323 template <typename... Args> auto gen_list(int size, Args &&...args) const {
324 std::vector<typename Gen::instance> res;
325
326 for (int i = 0; i < size; ++i)
327 res.push_back(static_cast<const Gen *>(this)->gen(
328 std::forward<Args>(args)...));
329
330 return typename sequence<typename Gen::instance>::instance(res);
331 }
332
333 // Calls the generator until predicate is true.
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)...);
339
340 if (predicate(inst))
341 return inst;
342 }
343
344 throw _detail::error("could not generate instance matching predicate");
345 }
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)...);
351 }
352
353 // Unique for generator.
354 template <typename... Args> auto unique(Args &&...args) const {
355 return tgen::unique(
356 [self = self()](auto &&...inner_args) mutable -> decltype(auto) {
357 return self.gen(
358 std::forward<decltype(inner_args)>(inner_args)...);
359 },
360 std::forward<Args>(args)...);
361 }
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)...);
365 }
366
367 // Nice error for `out << generator`.
368 friend std::ostream &operator<<(std::ostream &out, const gen_base &) {
369 static_assert(
370 _detail::dependent_false_v<gen_base>,
371 "cannot print a generator. Maybe you forgot to call `gen()`?");
372 return out;
373 }
374};
375
376// Base class for generator instances.
377template <typename Inst> struct gen_instance_base {
378 const Inst &self() const { return *static_cast<const Inst *>(this); }
379
380 bool operator<(const Inst &rhs) const {
381 return self().to_std() < rhs.to_std();
382 }
383};
384
385/*
386 * Type compile-time detection.
387 */
388
389// Detects associative containers.
390template <typename T, typename = void>
391struct is_associative_container : std::false_type {};
392template <typename T>
393struct is_associative_container<
394 T, std::void_t<typename T::key_type, typename T::key_compare>>
395 : std::true_type {};
396
397// Detects generator instances.
398template <typename T>
401
402// Detects sequential generator instances.
403template <typename T, typename = void>
404struct is_sequential : std::false_type {};
405template <typename T>
406struct is_sequential<
407 T, std::void_t<typename std::decay_t<T>::tgen_is_sequential_tag>>
408 : std::true_type {};
409
410// Detects generator instances with defined subset.
411template <typename T, typename = void>
412struct has_subset_defined : std::false_type {};
413template <typename T>
414struct has_subset_defined<
415 T, std::void_t<typename std::decay_t<T>::tgen_has_subset_defined_tag>>
416 : std::true_type {};
417
418/*
419 * Easier printing.
420 */
421
422// Struct to print standard types to std::ostream;
423struct print {
424 std::string s_;
425
426 template <typename T> print(const T &val, char sep = ' ') {
427 std::ostringstream oss;
428 write(oss, val, sep);
429 s_ = oss.str();
430 }
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);
435 s_ = oss.str();
436 }
437 template <typename T>
438 print(const std::initializer_list<std::initializer_list<T>> &il,
439 char sep = ' ') {
440 std::ostringstream oss;
441 std::vector<std::vector<T>> mat;
442 for (const auto &i : il)
443 mat.push_back(i);
444 write(oss, mat, sep);
445 s_ = oss.str();
446 }
447
448 template <typename T>
449 void write(std::ostream &os, const T &val, char sep = ' ') {
450 if constexpr (_detail::is_pair<T>::value) {
451 if constexpr (_detail::is_pair_multiline<T>::value) {
452 write(os, val.first, sep);
453 os << '\n';
454 write(os, val.second, sep);
455 } else {
456 write(os, val.first);
457 os << sep;
458 write(os, val.second);
459 }
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);
464 else
465 os << val;
466 }
467
468 // Writes container, checking separator.
469 template <typename C>
470 void write_container(std::ostream &os, const C &container, char sep = ' ') {
471 bool first = true;
472
473 for (const auto &e : container) {
474 if (!first)
475 os << (_detail::is_container_multiline<C>::value ? '\n' : sep);
476 first = false;
477 write(os, e, _detail::is_container_multiline<C>::value ? sep : ' ');
478 }
479 }
480
481 // Writes tuple, checking separator.
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...>) {
485 bool first = true;
486 ((os << (first ? (first = false, "")
487 : (_detail::is_tuple_multiline<Tuple>::value
488 ? "\n"
489 : std::string(1, sep))),
490 write(os, std::get<I>(tp),
491 _detail::is_tuple_multiline<Tuple>::value ? sep : ' ')),
492 ...);
493 }
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>{});
498 }
499
500 friend std::ostream &operator<<(std::ostream &out, const print &pr) {
501 return out << pr.s_;
502 }
503};
504
505// Prints in a new line.
506struct println : print {
507 template <typename T>
508 println(const T &val, char sep = ' ') : print(val, sep) {}
509 template <typename T>
510 println(const std::initializer_list<T> &il, char sep = ' ')
511 : print(il, sep) {}
512 template <typename T>
513 println(const std::initializer_list<std::initializer_list<T>> &il,
514 char sep = ' ')
515 : print(il, sep) {}
516
517 friend std::ostream &operator<<(std::ostream &out, const println &pr) {
518 return out << pr.s_ << '\n';
519 }
520};
521
522/*
523 * Global random operations.
524 */
525
526// Returns a random number in [0, n)
527// O(1).
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);
536 } else
537 throw _detail::error("invalid type for next (" +
538 std::string(typeid(T).name()) + ")");
539}
540
541// Returns a random number in [l, r].
542// O(1).
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);
550 else
551 throw _detail::error("invalid type for next (" +
552 std::string(typeid(T).name()) + ")");
553}
554
555// Returns i with probability proportional to distribution[i].
556template <typename T>
557size_t next_by_distribution(const std::vector<T> &distribution) {
558 tgen_ensure(distribution.size() > 0, "distribution must be non-empty");
559
560 T r = next<T>(
561 std::accumulate(distribution.begin(), distribution.end(), T(0)));
562 for (size_t i = 0; i < distribution.size(); ++i) {
563 if (r < distribution[i])
564 return i;
565 r -= distribution[i];
566 }
567 return distribution.size() - 1;
568}
569template <typename T>
570size_t next_by_distribution(const std::initializer_list<T> &distribution) {
571 return next_by_distribution(std::vector<T>(distribution));
572}
573
574// Shuffles [first, last) inplace uniformly, for RandomAccessIterator.
575// O(|container|).
576template <typename It> void shuffle(It first, It last) {
577 if (first == last)
578 return;
579
580 for (It i = first + 1; i != last; ++i)
581 std::iter_swap(i, first + next(0, static_cast<int>(i - first)));
582}
583
584// Shuffles sequential generator instance uniformly.
585// O(|inst|).
586template <typename Inst, std::enable_if_t<is_sequential<Inst>::value, int> = 0>
587void shuffle(Inst &inst) {
588 for (int i = 0; i < inst.size(); ++i)
589 std::swap(inst[i], inst[next(0, inst.size() - 1)]);
590}
591
592// Shuffles container uniformly.
593// O(|container|).
594template <typename C, std::enable_if_t<!is_associative_container<C>::value and
595 !is_generator_instance<C>::value,
596 int> = 0>
597[[nodiscard]] C shuffled(const C &container) {
598 auto new_container = container;
599 shuffle(new_container.begin(), new_container.end());
600 return new_container;
601}
602template <typename C,
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(),
606 container.end()));
607}
608template <typename T>
609[[nodiscard]] std::vector<T> shuffled(const std::initializer_list<T> &il) {
610 return shuffled(std::vector<T>(il));
611}
612
613// Shuffles sequential generator instance uniformly.
614// O(n).
615template <typename Inst, std::enable_if_t<is_sequential<Inst>::value, int> = 0>
616[[nodiscard]] Inst shuffled(const Inst &inst) {
617 Inst new_inst = inst;
618 shuffle(new_inst);
619 return new_inst;
620}
621
622// Returns a random element from [first, last) uniformly.
623// O(1) for random_access_iterator, O(|last - first|) otherwise.
624template <typename It> typename It::value_type any(It first, It last) {
625 int size = std::distance(first, last);
626 It it = first;
627 std::advance(it, next(0, size - 1));
628 return *it;
629}
630
631// Returns a random element from container uniformly.
632// O(1) for random_access_iterator, O(|container|) otherwise.
633template <typename C,
634 std::enable_if_t<!is_generator_instance<C>::value, int> = 0>
635typename C::value_type any(const C &container) {
636 return any(container.begin(), container.end());
637}
638template <typename T> T any(const std::initializer_list<T> &il) {
639 return any(std::vector<T>(il));
640}
641
642// Returns a random element from sequential generator instance uniformly.
643// O(1).
644template <typename Inst, std::enable_if_t<is_sequential<Inst>::value, int> = 0>
645typename Inst::value_type any(const Inst &inst) {
646 return inst[next<int>(0, inst.size() - 1)];
647}
648
649// Returns container[i] with probability proportional to distribution[i].
650// O(1) for random_access_iterator, O(|container|) otherwise.
651template <typename C, typename T,
652 std::enable_if_t<!is_generator_instance<C>::value, int> = 0>
653typename C::value_type any_by_distribution(const C &container,
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));
659 return *it;
660}
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));
667}
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);
672}
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));
678}
679
680// Returns inst[i] with probability proportional to distribution[i].
681// O(1).
682template <typename Inst, typename T,
683 std::enable_if_t<is_sequential<Inst>::value, int> = 0>
684typename Inst::value_type
685any_by_distribution(const Inst &inst, const std::vector<T> &distribution) {
686 tgen_ensure(inst.size() == distribution.size(),
687 "inst and distribution must have the same size");
688 return inst[next_by_distribution(distribution)];
689}
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));
696}
697
698// Chooses k values uniformly from container, as in a subsequence of size k.
699// Returns a copy. O(|container|).
700template <typename C,
701 std::enable_if_t<!is_generator_instance<C>::value, int> = 0>
702C choose(int k, const C &container) {
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;
706 C new_container;
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);
711 need--;
712 }
713 }
714 return new_container;
715}
716template <typename T>
717std::vector<T> choose(int k, const std::initializer_list<T> &il) {
718 return choose(k, std::vector<T>(il));
719}
720
721// Chooses k values uniformly from sequential generator instance, as in a
722// subsequence of size k.
723// O(n).
724template <typename Inst, std::enable_if_t<is_sequential<Inst>::value and
725 has_subset_defined<Inst>::value,
726 int> = 0>
727Inst choose(int k, const Inst &inst) {
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;
731 int need = k;
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]);
736 need--;
737 }
738 }
739 return Inst(new_vec);
740}
741
742// Number unique generator for integral types.
743template <typename T> struct unique_range {
744 T l_, r_;
745 T num_available_;
746 std::map<T, T> virtual_list_;
747
748 // Generator of unique values in [l_, r_].
749 unique_range(T l, T r) : l_(l), r_(r), num_available_(r - l + 1) {}
750
751 // Returns the number of unique values left to generate.
752 T size() const { return num_available_; }
753
754 // Generates a random value in [l_, r_] that has not been generated yet.
755 // O(log n).
756 T gen() {
757 // One iteration of Fisher–Yates.
758 tgen_ensure(size() > 0, "unique_range: no more values to generate");
759
760 T i = next<T>(0, size() - 1);
761 T j = size() - 1;
762
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;
766
767 --num_available_;
768
769 return vi + l_;
770 }
771
772 // Generates a list of unique values.
773 // O(size * log(n)).
774 auto gen_list(int size) {
775 std::vector<T> res;
776 for (int i = 0; i < size; ++i)
777 res.push_back(gen());
778 return typename sequence<T>::instance(res);
779 }
780
781 // Generates all unique values.
782 // O(n log(n))
783 auto gen_all() {
784 std::vector<T> res;
785 while (size() > 0)
786 res.push_back(gen());
787 return typename sequence<T>::instance(res);
788 }
789};
790
791// Unique generator for containers.
792template <typename T> struct unique_container {
793 std::vector<T> list_;
794 unique_range<size_t> idx_;
795
796 // Creates a unique container generator for the given container.
797 template <typename C>
798 unique_container(const C &container)
800 idx_(0, static_cast<int>(container.size()) - 1) {}
801 unique_container(const std::initializer_list<T> &il)
802 : unique_container(std::vector<T>(il)) {}
803
804 // Returns the number of unique elements left to generate.
805 size_t size() const { return idx_.size(); }
806
807 // Generates a random element from container uniformly.
808 // O(log n).
809 T gen() { return list_[idx_.gen()]; }
810
811 // Generates a list of unique values.
812 // O(size * log(n)).
813 auto gen_list(int size) {
814 std::vector<T> res;
815 for (int i = 0; i < size; ++i)
816 res.push_back(gen());
817 return typename sequence<T>::instance(res);
818 }
819
820 // Generates all unique values.
821 // O(n log(n))
822 auto gen_all() {
823 std::vector<T> res;
824 while (size() > 0)
825 res.push_back(gen());
826 return typename sequence<T>::instance(res);
827 }
828};
829template <typename C>
830unique_container(const C &) -> unique_container<typename C::value_type>;
831
832/************
833 * *
834 * OPTS *
835 * *
836 ************/
837
838/*
839 * Opts - options given to the generator.
840 *
841 * Incompatible with testlib.
842 *
843 * Opts are a list of either positional or named options.
844 *
845 * Named options is given in one of the following formats:
846 * 1) -keyname=value or --keyname=value (ex. -n=10 , --test-count=20)
847 * 2) -keyname value or --keyname value (ex. -n 10 , --test-count 20)
848 *
849 * Positional options are number from 0 sequentially.
850 * For example, for "10 -n=20 str" positional option 1 is the string "str".
851 */
852
853/*
854 * C++ version selection.
855 */
856
857// Sets C++ version.
858inline void set_cpp_version(int version) {
859 _detail::cpp = _detail::cpp_value(version);
860}
861
862/*
863 * Compiler selection.
864 */
865
866// GCC compiler type.
867inline _detail::compiler_value gcc(int major = 0, int minor = 0) {
868 return {_detail::compiler_kind::gcc, major, minor};
869}
870
871// Clang compiler type.
872inline _detail::compiler_value clang(int major = 0, int minor = 0) {
873 return {_detail::compiler_kind::clang, major, minor};
874}
875
876// Sets compiler.
877inline void set_compiler(_detail::compiler_value compiler) {
878 _detail::compiler.kind_ = compiler.kind_;
879 _detail::compiler.major_ = compiler.major_;
880 _detail::compiler.minor_ = compiler.minor_;
881}
882
883namespace _detail {
884
885// Processes special opt flags.
886// Returns true if the key is a special opt flag.
887inline bool process_special_opt_flags(std::string &key) {
888 // Checks for gen::CPP=17|20|23
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));
896 set_cpp_version(version);
897 return true;
898 }
899
900 // Checks for tgen::(GCC|CLANG) or
901 // tgen::(GCC|CLANG):(version|version.minor).
902 _detail::compiler_kind kind;
903 size_t prefix_len = 0;
904
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();
911 } else {
912 return false;
913 }
914
915 if (key.size() == prefix_len) {
916 set_compiler(compiler_value(kind, 0, 0));
917 return true;
918 }
919
920 tgen_ensure(key[prefix_len] == ':', "invalid compiler format");
921 ++prefix_len; // for ':'.
922
923 std::string inside = key.substr(prefix_len, key.size() - prefix_len);
924 int major = 0, minor = 0;
925
926 size_t dot = inside.find('.');
927 if (dot == std::string::npos) {
928 tgen_ensure(!inside.empty() and
929 std::all_of(inside.begin(), inside.end(), ::isdigit),
930 "invalid compiler version");
931 major = std::stoi(inside);
932 } else {
933 std::string maj = inside.substr(0, dot);
934 std::string min = inside.substr(dot + 1);
935
936 tgen_ensure(!maj.empty() and
937 std::all_of(maj.begin(), maj.end(), ::isdigit) and
938 maj.size() <= 3,
939 "invalid compiler major version");
940 tgen_ensure(!min.empty() and
941 std::all_of(min.begin(), min.end(), ::isdigit) and
942 min.size() <= 3,
943 "invalid compiler minor version");
944
945 major = std::stoi(maj);
946 minor = std::stoi(min);
947 }
948
949 set_compiler(compiler_value(kind, major, minor));
950
951 return true;
952}
953
954inline std::vector<std::string>
955 pos_opts; // Dictionary containing the positional parsed opts.
956inline std::map<std::string, std::string>
957 named_opts; // Global dictionary the named parsed opts.
958
959template <typename T> T get_opt(const std::string &value) {
960 try {
961 if constexpr (std::is_same_v<T, bool>) {
962 if (value == "true" or value == "1")
963 return true;
964 if (value == "false" or value == "0")
965 return false;
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));
969 else
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));
973 else
974 return value; // default: std::string
975 } catch (...) {
976 }
977
978 throw _detail::error("invalid value `" + value + "` for type " +
979 typeid(T).name());
980}
981
982inline void parse_opts(int argc, char **argv) {
983 // Parses the opts into `pos_opts` vector and `named_opts`
984 // map. Starting from 1 to ignore the name of the executable.
985 for (int i = 1; i < argc; ++i) {
986 std::string key(argv[i]);
987
988 if (process_special_opt_flags(key))
989 continue;
990
991 if (key[0] == '-') {
992 tgen_ensure(key.size() > 1,
993 "invalid opt (" + std::string(argv[i]) + ")");
994 if ('0' <= key[1] and key[1] <= '9') {
995 // This case is a positional negative number argument
996 _detail::pos_opts.push_back(key);
997 continue;
998 }
999
1000 // pops first char '-'
1001 key = key.substr(1);
1002 } else {
1003 // This case is a positional argument that does not start with '-'
1004 _detail::pos_opts.push_back(key);
1005 continue;
1006 }
1007
1008 // Pops a possible second char '-'.
1009 if (key[0] == '-') {
1010 tgen_ensure(key.size() > 1,
1011 "invalid opt (" + std::string(argv[i]) + ")");
1012
1013 // pops first char '-'
1014 key = key.substr(1);
1015 }
1016
1017 // Assumes that, if it starts with '-' and second char is not a digit,
1018 // then it is a <key, value> pair.
1019 // 1 or 2 chars '-' have already been poped.
1020
1021 std::size_t eq = key.find('=');
1022 if (eq != std::string::npos) {
1023 // This is the '--key=value' case.
1024 std::string value = key.substr(eq + 1);
1025 key = key.substr(0, eq);
1026 tgen_ensure(!key.empty() and !value.empty(),
1027 "expected non-empty key/value in opt (" +
1028 std::string(argv[1]));
1029 tgen_ensure(_detail::named_opts.count(key) == 0,
1030 "cannot have repeated keys");
1031 _detail::named_opts[key] = value;
1032 } else {
1033 // This is the '--key value' case.
1034 tgen_ensure(_detail::named_opts.count(key) == 0,
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]);
1038 ++i;
1039 }
1040 }
1041}
1042
1043inline void set_seed(int argc, char **argv) {
1044 std::vector<uint32_t> seed;
1045
1046 // Starting from 1 to ignore the name of the executable.
1047 for (int i = 1; i < argc; ++i) {
1048 // We append the number of chars, and then the list of chars.
1049 int size_pos = seed.size();
1050 seed.push_back(0);
1051 for (char *s = argv[i]; *s != '\0'; ++s) {
1052 ++seed[size_pos];
1053 seed.push_back(*s);
1054 }
1055 }
1056 std::seed_seq seq(seed.begin(), seed.end());
1057 _detail::rng.seed(seq);
1058}
1059
1060} // namespace _detail
1061
1062// Returns true if there is an opt at a given index.
1063inline bool has_opt(std::size_t index) {
1064 tgen::_detail::ensure_registered();
1065 return 0 <= index and index < _detail::pos_opts.size();
1066}
1067
1068// Returns true if there is an opt with a given key.
1069inline bool has_opt(const std::string &key) {
1070 tgen::_detail::ensure_registered();
1071 return _detail::named_opts.count(key) != 0;
1072}
1073
1074// Returns the parsed opt by a given index. If no opts with the given index are
1075// found, returns the given default_value.
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)) {
1080 if (default_value)
1081 return *default_value;
1082 throw _detail::error("cannot find key with index " +
1083 std::to_string(index));
1084 }
1085 return _detail::get_opt<T>(_detail::pos_opts[index]);
1086}
1087
1088// Returns the parsed opt by a given key. If no opts with the given key are
1089// found, returns the given default_value.
1090template <typename T>
1091T opt(const std::string &key, std::optional<T> default_value = std::nullopt) {
1092 tgen::_detail::ensure_registered();
1093 if (!has_opt(key)) {
1094 if (default_value)
1095 return *default_value;
1096 throw _detail::error("cannot find key with key " + key);
1097 }
1098 return _detail::get_opt<T>(_detail::named_opts[key]);
1099}
1100
1101// Registers generator by initializing rnd and parsing opts.
1102inline void register_gen(int argc, char **argv) {
1103 _detail::set_seed(argc, argv);
1104
1105 _detail::pos_opts.clear();
1106 _detail::named_opts.clear();
1107 _detail::parse_opts(argc, argv);
1108
1109 _detail::registered = true;
1110}
1111
1112// Registers generator by initializing rnd with a given seed.
1113inline void register_gen(std::optional<long long> seed = std::nullopt) {
1114 if (seed)
1115 _detail::rng.seed(*seed);
1116 else
1117 _detail::rng.seed();
1118
1119 _detail::pos_opts.clear();
1120 _detail::named_opts.clear();
1121
1122 _detail::registered = true;
1123}
1124
1125/****************
1126 * *
1127 * SEQUENCE *
1128 * *
1129 ****************/
1130
1131/*
1132 * Sequence generator.
1133 */
1134
1135template <typename T> struct sequence : gen_base<sequence<T>> {
1136 int size_; // Size of sequence.
1137 T value_l_, value_r_; // Range of defined values.
1138 std::set<T> values_; // Set of values. If empty, use range. if not,
1139 // represents the possible values, and the range
1140 // represents the index in this set)
1141 std::map<T, int>
1142 value_idx_in_set_; // Index of every value in the set above.
1143 std::vector<std::pair<T, T>> val_range_; // Range of values of each index.
1144 std::vector<std::vector<int>> neigh_; // Adjacency list of equality.
1145 std::vector<std::set<int>>
1146 distinct_restrictions_; // All distinct restrictions.
1147
1148 // Creates generator for sequences of size 'size', with random T in [l, r].
1149 sequence(int size, T value_l, T value_r)
1150 : size_(size), value_l_(value_l), value_r_(value_r), neigh_(size) {
1151 tgen_ensure(size_ > 0, "sequence: size must be positive");
1152 tgen_ensure(value_l_ <= value_r_,
1153 "sequence: value range must be valid");
1154 for (int i = 0; i < size_; ++i)
1155 val_range_.emplace_back(value_l_, value_r_);
1156 }
1157
1158 // Creates sequence with value set.
1159 sequence(int size, std::set<T> values)
1160 : size_(size), values_(values), neigh_(size) {
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_);
1166 int idx = 0;
1167 for (T value : values_)
1168 value_idx_in_set_[value] = idx++;
1169 }
1170
1171 // Restricts sequences for sequence[idx] = value.
1172 sequence &fix(int idx, T value) {
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_) {
1177 tgen_ensure(left == value,
1178 "sequence: must not set to two different values");
1179 } else {
1180 tgen_ensure(left <= value and value <= right,
1181 "sequence: value must be in the defined range");
1182 }
1183 left = right = value;
1184 } else {
1185 tgen_ensure(values_.count(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];
1189 tgen_ensure(left <= new_val and new_val <= right,
1190 "sequence: must not set to two different values");
1191 left = right = new_val;
1192 }
1193 return *this;
1194 }
1195
1196 // Restricts sequences for sequence[idx_1] = sequence[idx_2].
1197 sequence &equal(int idx_1, int idx_2) {
1198 tgen_ensure(0 <= std::min(idx_1, idx_2) and
1199 std::max(idx_1, idx_2) < size_,
1200 "sequence: indices must be valid");
1201 if (idx_1 == idx_2)
1202 return *this;
1203
1204 neigh_[idx_1].push_back(idx_2);
1205 neigh_[idx_2].push_back(idx_1);
1206 return *this;
1207 }
1208
1209 // Restricts sequences for sequence[left..right] to have all equal values.
1210 sequence &equal_range(int left, int right) {
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)
1214 equal(i, i + 1);
1215 return *this;
1216 }
1217
1218 // Restricts sequences for sequence[S] to be distinct, for given subset S of
1219 // indices.
1220 // You can not add two of these restrictions with intersection.
1221 sequence &distinct(std::set<int> indices) {
1222 if (!indices.empty())
1223 distinct_restrictions_.push_back(indices);
1224 return *this;
1225 }
1226
1227 // Restricts sequences for sequence[idx_1] != sequence[idx_2].
1228 sequence &different(int idx_1, int idx_2) {
1229 std::set<int> indices = {idx_1, idx_2};
1230 return distinct(indices);
1231 }
1232
1233 // Restricts sequences with distinct elements.
1235 std::vector<int> indices(size_);
1236 std::iota(indices.begin(), indices.end(), 0);
1237 return distinct(std::set<int>(indices.begin(), indices.end()));
1238 }
1239
1240 // Sequence instance.
1241 // Operations on an instance are not random.
1243 using tgen_is_sequential_tag = _detail::is_sequential_tag;
1244 using tgen_has_subset_defined_tag = _detail::has_subset_defined_tag;
1245
1246 using value_type = T; // Value type, for templates.
1247 using std_type = std::vector<T>; // std type for instance.
1248 std::vector<T> vec_; // Sequence.
1249 char sep_; // Separator for printing.
1250
1251 instance(const std::vector<T> &vec) : vec_(vec), sep_(' ') {}
1252 instance(const std::initializer_list<T> &il)
1253 : instance(std::vector<T>(il)) {}
1254
1255 // Fetches size.
1256 int size() const { return vec_.size(); }
1257
1258 // Fetches position idx.
1259 T &operator[](int idx) {
1260 tgen_ensure(0 <= idx and idx < size(),
1261 "sequence: instance: index out of bounds");
1262 return vec_[idx];
1263 }
1264 const T &operator[](int idx) const {
1265 tgen_ensure(0 <= idx and idx < size(),
1266 "sequence: instance: index out of bounds");
1267 return vec_[idx];
1268 }
1269
1270 // Sorts values in non-decreasing order.
1271 // O(n log n).
1273 std::sort(vec_.begin(), vec_.end());
1274 return *this;
1275 }
1276
1277 // Reverses sequence.
1278 // O(n).
1280 std::reverse(vec_.begin(), vec_.end());
1281 return *this;
1282 }
1283
1284 // Sets the separator for the sequence, for printing.
1285 // O(1).
1286 instance &separator(char sep) {
1287 sep_ = sep;
1288 return *this;
1289 }
1290
1291 // Concatenates two instances.
1292 // Linear.
1294 std::vector<T> new_vec = vec_;
1295 for (int i = 0; i < rhs.size(); ++i)
1296 new_vec.push_back(rhs[i]);
1297 return instance(new_vec);
1298 }
1299
1300 // Prints to std::ostream, separated by spaces.
1301 friend std::ostream &operator<<(std::ostream &out,
1302 const instance &inst) {
1303 for (int i = 0; i < inst.size(); ++i) {
1304 if (i > 0)
1305 out << inst.sep_;
1306 out << inst[i];
1307 }
1308 return out;
1309 }
1310
1311 // Gets a std::vector representing the instance.
1312 std::vector<T> to_std() const { return vec_; }
1313 };
1314
1315 // Generates a uniformly random list of k distinct values in `[value_l,
1316 // value_r]`, such that no value is in `forbidden_values`.
1317 std::vector<T>
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_);
1321 // We generate our numbers in the range [0, num_available) with
1322 // num_available = (r-l+1)-(forbidden_values.size()), and then map them
1323 // to the correct range. We will run k steps of Fisher–Yates, using a
1324 // map to store a virtual sequence that starts with a[i] = i.
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;
1335
1336 virtual_list[j] = vi, virtual_list[i] = vj;
1337
1338 gen_list.push_back(virtual_list[i]);
1339 }
1340
1341 // Shifts back to correct range, but there might still be values
1342 // that we can not use.
1343 for (T &value : gen_list)
1344 value += value_l_;
1345
1346 // Now for every generated value, we shift it by how many forbidden
1347 // values are <= to it.
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);
1351 // We iterate through them in increasing order.
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;
1360 }
1361
1362 return gen_list;
1363 }
1364
1365 // Generates sequence instance.
1366 // O(n log n).
1367 instance gen() const {
1368 std::vector<T> vec(size_);
1369 std::vector<bool> defined_idx(
1370 size_, false); // For every index, if it has been set in `vec`.
1371
1372 std::vector<int> comp_id(size_, -1); // Component id of each index.
1373 std::vector<std::vector<int>> comp(size_); // Component of each comp-id.
1374 int comp_count = 0; // Number of different components.
1375
1376 // Defines value of entire component.
1377 auto define_comp = [&](int cur_comp, T val) {
1378 for (int idx : comp[cur_comp]) {
1379 tgen_ensure(!defined_idx[idx]);
1380 vec[idx] = val;
1381 defined_idx[idx] = true;
1382 }
1383 };
1384
1385 // Groups = components.
1386 {
1387 std::vector<bool> vis(size_, false); // Visited for each index.
1388 for (int idx = 0; idx < size_; ++idx)
1389 if (!vis[idx]) {
1390 T new_value;
1391 bool value_defined = false;
1392
1393 // BFS to visit the connected component, grouping equal
1394 // values.
1395 std::queue<int> q({idx});
1396 vis[idx] = true;
1397 std::vector<int> component;
1398 while (!q.empty()) {
1399 int cur_idx = q.front();
1400 q.pop();
1401
1402 component.push_back(cur_idx);
1403
1404 // Checks value.
1405 auto [l, r] = val_range_[cur_idx];
1406 if (l == r) {
1407 if (!value_defined) {
1408 // We found the value.
1409 value_defined = true;
1410 new_value = l;
1411 } else if (new_value != l) {
1412 // We found a contradiction
1413 throw _detail::contradiction_error(
1414 "sequence",
1415 "tried to set value to `" +
1416 std::to_string(new_value) +
1417 "`, but it was already set as `" +
1418 std::to_string(l) + "`");
1419 }
1420 }
1421
1422 for (int nxt_idx : neigh_[cur_idx]) {
1423 if (!vis[nxt_idx]) {
1424 vis[nxt_idx] = true;
1425 q.push(nxt_idx);
1426 }
1427 }
1428 }
1429
1430 // Group entire component, checking if value is defined.
1431 for (int cur_idx : component) {
1432 comp_id[cur_idx] = comp_count;
1433 comp[comp_id[cur_idx]].push_back(cur_idx);
1434 }
1435
1436 // Defines value if needed.
1437 if (value_defined)
1438 define_comp(comp_count, new_value);
1439
1440 ++comp_count;
1441 }
1442 }
1443
1444 // Initial parsing of distinct restrictions.
1445 std::vector<std::set<int>> distinct_containing_comp_idx(comp_count);
1446 {
1447 int dist_id = 0;
1448 for (const std::set<int> &distinct : distinct_restrictions_) {
1449 // Checks if there are too many distinct values.
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(
1454 "sequence",
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));
1458
1459 // Checks if two values in same component are marked as
1460 // different.
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 "
1466 "different");
1467 comp_ids.insert(comp_id[idx]);
1468
1469 distinct_containing_comp_idx[comp_id[idx]].insert(dist_id);
1470 }
1471 ++dist_id;
1472 }
1473 }
1474
1475 // If some value is in >= 3 sets, then there is a cycle.
1476 for (auto &distinct_containing : distinct_containing_comp_idx)
1477 if (distinct_containing.size() >= 3)
1478 throw _detail::complex_restrictions_error(
1479 "sequence",
1480 "one index can not be in >= 3 distinct restrictions");
1481
1482 std::vector<bool> vis_distinct(distinct_restrictions_.size(), false);
1483 std::vector<bool> initially_defined_comp_idx(comp_count, false);
1484
1485 // Fills the value in a tree defined by distinct restrictions.
1486 auto define_tree = [&](int distinct_id) {
1487 // The set `distinct_restrictions_[distinct_id]` can have some
1488 // values that are defined.
1489
1490 // Generates set of already defined values.
1491 std::set<T> defined_values;
1492 for (int idx : distinct_restrictions_[distinct_id])
1493 if (defined_idx[idx]) {
1494 // Checks if two values in `distinct_restrictions_[dist_id]`
1495 // have been set to the same value
1496 if (defined_values.count(vec[idx]))
1497 throw _detail::contradiction_error(
1498 "sequence",
1499 "tried to set two indices as equal and different");
1500
1501 defined_values.insert(vec[idx]);
1502 }
1503
1504 // Generates values in this root distinct restriction.
1505 {
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]) {
1514 // The root can cover these components, but there should
1515 // not be any other defined in this tree.
1516 initially_defined_comp_idx[comp_id[idx]] = false;
1517 } else {
1518 define_comp(comp_id[idx], *val_it);
1519 ++val_it;
1520 }
1521 }
1522
1523 // BFS on the tree of distinct restrictions.
1524 std::queue<std::pair<int, int>> q; // {id, parent id}
1525 q.emplace(distinct_id, -1);
1526 vis_distinct[distinct_id] = true;
1527 while (!q.empty()) {
1528 auto [cur_distinct, parent] = q.front();
1529 q.pop();
1530
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)
1537 continue;
1538
1539 // Cycle found.
1540 if (vis_distinct[nxt_distinct])
1541 throw _detail::complex_restrictions_error(
1542 "sequence",
1543 "cycle found in distinct restrictions");
1544
1545 neigh_distinct.insert(nxt_distinct);
1546 }
1547
1548 for (int nxt_distinct : neigh_distinct) {
1549 vis_distinct[nxt_distinct] = true;
1550 q.emplace(nxt_distinct, cur_distinct);
1551
1552 // Generates this distinct restriction.
1553 std::set<T> nxt_defined_values;
1554 for (int idx2 : distinct_restrictions_[nxt_distinct])
1555 if (defined_idx[idx2]) {
1556 // There can not be any more defined. This case is
1557 // when there are values not coverered by a single
1558 // distinct restriction in the tree.
1559 if (initially_defined_comp_idx[comp_id[idx2]])
1560 throw _detail::complex_restrictions_error(
1561 "sequence");
1562
1563 nxt_defined_values.insert(vec[idx2]);
1564 }
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);
1574 ++val_it;
1575 }
1576 }
1577 }
1578 };
1579
1580 // Loops through distinct restrictions, sorts distinct restrictions
1581 // by number of defined components (non-increasing). This guarantees
1582 // that if there is a valid root (that covers all 'defined'), we find
1583 // it.
1584 {
1585 std::vector<std::pair<int, int>> defined_cnt_and_distinct_idx;
1586 int dist_id = 0;
1587 for (const std::set<int> &distinct : distinct_restrictions_) {
1588 int defined_cnt = 0;
1589 for (int idx : distinct)
1590 if (defined_idx[idx]) {
1591 ++defined_cnt;
1592 initially_defined_comp_idx[comp_id[idx]] = true;
1593 }
1594 defined_cnt_and_distinct_idx.emplace_back(defined_cnt, dist_id);
1595 ++dist_id;
1596 }
1597
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);
1604 }
1605
1606 // Loops through distinct restrictions do define the rest.
1607 for (std::size_t dist_id = 0; dist_id < distinct_restrictions_.size();
1608 ++dist_id)
1609 if (!vis_distinct[dist_id])
1610 define_tree(dist_id);
1611
1612 // Define final values. These values all should be random in [l, r], and
1613 // the distinct restrictions have already been processed. However, there
1614 // can be still equality restrictions, so we define entire components.
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_));
1618
1619 if (!values_.empty()) {
1620 // Needs to fetch the values from the value set.
1621 std::vector<T> value_vec(values_.begin(), values_.end());
1622 for (T &val : vec)
1623 val = value_vec[val];
1624 }
1625
1626 return instance(vec);
1627 }
1628};
1629
1630/*******************
1631 * *
1632 * PERMUTATION *
1633 * *
1634 *******************/
1635
1636/*
1637 * Permutation generation.
1638 *
1639 * Permutation are defined always as numbers in [0, n), that is, 0-based.
1640 */
1641
1643 int size_; // Size of permutation.
1644 std::vector<std::pair<int, int>> defs_; // {idx, value}.
1645 std::optional<std::vector<int>> cycle_sizes_; // Cycle sizes.
1646
1647 // Creates generator for permutation of size 'size'.
1648 permutation(int size) : size_(size) {
1649 tgen_ensure(size_ > 0, "permutation: size must be positive");
1650 }
1651
1652 // Restricts sequences for permutation[idx] = value.
1653 permutation &fix(int idx, int value) {
1654 tgen_ensure(0 <= idx and idx < size_,
1655 "permutation: index must be valid");
1656 defs_.emplace_back(idx, value);
1657 return *this;
1658 }
1659
1660 // Restricts sequences for permutation to have cycle sizes.
1661 permutation &cycles(const std::vector<int> &cycle_sizes) {
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;
1666 return *this;
1667 }
1668 permutation &cycles(const std::initializer_list<int> &cycle_sizes) {
1669 return cycles(std::vector<int>(cycle_sizes));
1670 }
1671
1672 // Permutation instance.
1673 // Operations on an instance are not random.
1675 using tgen_is_sequential_tag = _detail::is_sequential_tag;
1676
1677 using std_type = std::vector<int>; // std type for instance.
1678 std::vector<int> vec_; // Permutation.
1679 char sep_; // Separator for printing.
1680 bool add_1_; // If should add 1, for printing.
1681
1682 instance(const std::vector<int> &vec)
1683 : vec_(vec), sep_(' '), add_1_(false) {
1684 tgen_ensure(!vec_.empty(),
1685 "permutation: instance: cannot be empty");
1686 std::vector<bool> vis(vec_.size(), false);
1687 for (int i = 0; i < size(); ++i) {
1688 tgen_ensure(0 <= vec_[i] and
1689 vec_[i] < static_cast<int>(vec_.size()),
1690 "permutation: instance: values must be from `0` to "
1691 "`size-1`");
1693 !vis[vec_[i]],
1694 "permutation: instance: cannot have repeated values");
1695 vis[vec_[i]] = true;
1696 }
1697 }
1698 instance(const std::initializer_list<int> &il)
1699 : instance(std::vector<int>(il)) {}
1700
1701 // Fetches size.
1702 int size() const { return vec_.size(); }
1703
1704 // Fetches position idx.
1705 const int &operator[](int idx) const {
1706 tgen_ensure(0 <= idx and idx < size(),
1707 "permutation: instance: index out of bounds");
1708 return vec_[idx];
1709 }
1710
1711 // Returns parity of the permutation (+1 if even, -1 if odd).
1712 // O(n).
1713 int parity() const {
1714 std::vector<bool> vis(size(), false);
1715 int cycles = 0;
1716
1717 for (int i = 0; i < size(); ++i)
1718 if (!vis[i]) {
1719 cycles++;
1720 for (int j = i; !vis[j]; j = vec_[j])
1721 vis[j] = true;
1722 }
1723 // Even iff (n - cycles) is even.
1724 return ((size() - cycles) % 2 == 0) ? +1 : -1;
1725 }
1726
1727 // Sorts values in increasign order.
1728 // O(n).
1730 for (int i = 0; i < size(); ++i)
1731 vec_[i] = i;
1732 return *this;
1733 }
1734
1735 // Reverses permutation.
1736 // O(n).
1738 std::reverse(vec_.begin(), vec_.end());
1739 return *this;
1740 }
1741
1742 // Inverse of the permutation.
1743 // O(n).
1745 std::vector<int> inv(size());
1746 for (int i = 0; i < size(); ++i)
1747 inv[vec_[i]] = i;
1748 swap(vec_, inv);
1749 return *this;
1750 }
1751
1752 // Sets the separator, for printing.
1753 // O(1).
1754 instance &separator(char sep) {
1755 sep_ = sep;
1756 return *this;
1757 }
1758
1759 // Sets that should print values 1-based.
1760 // O(1).
1762 add_1_ = true;
1763 return *this;
1764 }
1765
1766 // Prints to std::ostream, separated by spaces.
1767 friend std::ostream &operator<<(std::ostream &out,
1768 const instance &inst) {
1769 for (int i = 0; i < inst.size(); ++i) {
1770 if (i > 0)
1771 out << inst.sep_;
1772 out << inst[i] + inst.add_1_;
1773 }
1774 return out;
1775 }
1776
1777 // Gets a std::vector representing the instance.
1778 std::vector<int> to_std() const { return vec_; }
1779 };
1780
1781 // Generates permutation instance.
1782 // O(n).
1783 instance gen() const {
1784 if (!cycle_sizes_) {
1785 // Cycle sizes not specified.
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_) + ")");
1792
1793 if (idx_to_val[idx] != -1) {
1794 tgen_ensure(idx_to_val[idx] == val,
1795 "permutation: cannot set an idex to two "
1796 "different values");
1797 } else
1798 idx_to_val[idx] = val;
1799
1800 if (val_to_idx[val] != -1) {
1801 tgen_ensure(val_to_idx[val] == idx,
1802 "permutation: cannot set two indices to the "
1803 "same value");
1804 } else
1805 val_to_idx[val] = idx;
1806 }
1807
1808 std::vector<int> perm(size_);
1809 std::iota(perm.begin(), perm.end(), 0);
1810 shuffle(perm.begin(), perm.end());
1811 int cur_idx = 0;
1812 for (int &i : idx_to_val)
1813 if (i == -1) {
1814 // While this value is used, skip.
1815 while (val_to_idx[perm[cur_idx]] != -1)
1816 ++cur_idx;
1817 i = perm[cur_idx++];
1818 }
1819 return idx_to_val;
1820 }
1821
1822 // Creates cycles.
1823 std::vector<int> order(size_);
1824 std::iota(order.begin(), order.end(), 0);
1825 shuffle(order.begin(), order.end());
1826 int idx = 0;
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++]);
1832 }
1833
1834 // Retrieves permutation from cycles.
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];
1840 }
1841
1842 return instance(perm);
1843 }
1844};
1845
1846/************
1847 * *
1848 * MATH *
1849 * *
1850 ************/
1851
1852namespace math {
1853
1854namespace _detail {
1855
1856inline int popcount(uint64_t x) { return __builtin_popcountll(x); }
1857
1858inline int ctzll(uint64_t x) {
1859 // Mistery code found on the internet.
1860 // Uses de Brujin sequence.
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];
1867}
1868
1869inline uint64_t mul_mod(uint64_t a, uint64_t b, uint64_t m) {
1870 return static_cast<unsigned __int128>(a) * b % m;
1871}
1872
1873// O(log n).
1874// 0 <= x < m.
1875inline uint64_t expo_mod(uint64_t x, uint64_t y, uint64_t m) {
1876 if (!y)
1877 return 1;
1878 uint64_t ans = expo_mod(mul_mod(x, x, m), y / 2, m);
1879 return y % 2 ? mul_mod(x, ans, m) : ans;
1880}
1881
1882} // namespace _detail
1883
1884// O(log^2 n).
1885inline bool is_prime(uint64_t n) {
1886 if (n < 2)
1887 return false;
1888 if (n == 2 or n == 3)
1889 return true;
1890 if (n % 2 == 0)
1891 return false;
1892
1893 uint64_t r = _detail::ctzll(n - 1), d = n >> r;
1894 // These bases are guaranteed to work for n <= 2^64.
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)
1898 continue;
1899
1900 for (uint64_t j = 0; j < r - 1; ++j) {
1901 x = _detail::mul_mod(x, x, n);
1902 if (x == n - 1)
1903 break;
1904 }
1905 if (x != n - 1)
1906 return false;
1907 }
1908 return true;
1909}
1910
1911namespace _detail {
1912
1913inline uint64_t pollard_rho(uint64_t n) {
1914 if (n == 1 or is_prime(n))
1915 return n;
1916 auto f = [n](uint64_t x) { return mul_mod(x, x, n) + 1; };
1917
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) {
1920 if (x == y)
1921 x = ++x0, y = f(x);
1922 q = mul_mod(prd, x > y ? x - y : y - x, n);
1923 if (q != 0)
1924 prd = q;
1925 x = f(x), y = f(f(y)), t++;
1926 }
1927 return std::gcd(prd, n);
1928}
1929
1930inline std::vector<uint64_t> factor(uint64_t n) {
1931 if (n == 1)
1932 return {};
1933 if (is_prime(n))
1934 return {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());
1938 return l;
1939}
1940
1941// Error handling.
1942template <typename T>
1943std::runtime_error there_is_no_in_range_error(const std::string &type, T l,
1944 T r) {
1945 return tgen::_detail::error("math: there is no " + type + " in range [" +
1946 std::to_string(l) + ", " + std::to_string(r) +
1947 "]");
1948}
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 " +
1952 std::to_string(r));
1953}
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 " +
1957 std::to_string(r));
1958}
1959
1960// O(log mod).
1961// 0 < a < mod.
1962// gcd(a, mod) = 1.
1963inline __int128 modular_inverse_128(__int128 a, __int128 mod) {
1964 tgen_ensure(0 < a and a < mod,
1965 "math: remainder must be positive and smaller than the mod");
1966
1967 __int128 t = 0, new_t = 1;
1968 __int128 r = mod, new_r = a;
1969
1970 while (new_r != 0) {
1971 __int128 q = r / new_r;
1972
1973 auto tmp_t = t - q * new_t;
1974 t = new_t;
1975 new_t = tmp_t;
1976
1977 auto tmp_r = r - q * new_r;
1978 r = new_r;
1979 new_r = tmp_r;
1980 }
1981
1982 tgen_ensure(r == 1, "math: remainder and mod must be coprime");
1983
1984 if (t < 0)
1985 t += mod;
1986 return t;
1987}
1988
1989// checks if a * b <= limit, for positive numbers.
1990inline bool mul_leq(uint64_t a, uint64_t b, uint64_t limit) {
1991 if (a == 0)
1992 return true;
1993 return a <= limit / b;
1994}
1995
1996// base^exp, or null if base^exp > limit.
1997inline std::optional<uint64_t> expo(uint64_t base, uint64_t exp,
1998 uint64_t limit) {
1999 uint64_t result = 1;
2000
2001 while (exp) {
2002 if (exp & 1) {
2003 if (!mul_leq(result, base, limit))
2004 return std::nullopt;
2005 result *= base;
2006 }
2007
2008 exp >>= 1;
2009 // Necesary for correctness.
2010 if (!exp)
2011 break;
2012
2013 if (!mul_leq(base, base, limit))
2014 return std::nullopt;
2015 base *= base;
2016 }
2017 return result;
2018}
2019
2020// O(log n log k).
2021// 0 <= n.
2022// 0 < k.
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)
2027 return n;
2028
2029 uint64_t lo = 1, hi = 1ULL << ((64 + k - 1) / k);
2030
2031 while (lo < hi) {
2032 uint64_t mid = lo + (hi - lo + 1) / 2;
2033
2034 if (expo(mid, k, n)) {
2035 lo = mid;
2036 } else {
2037 hi = mid - 1;
2038 }
2039 }
2040 return lo;
2041}
2042
2043// gcd(a, b).
2044// O(log a).
2045inline __int128 gcd128(__int128 a, __int128 b) {
2046 if (a < 0)
2047 a = -a;
2048 if (b < 0)
2049 b = -b;
2050 while (b != 0) {
2051 __int128 t = a % b;
2052 a = b;
2053 b = t;
2054 }
2055 return a;
2056}
2057
2058// min(2^64, a*b).
2059// O(log a).
2060// a, b >= 0.
2061inline __int128 mul_saturate(__int128 a, __int128 b) {
2062 tgen_ensure(a >= 0 and b >= 0);
2063 static const __int128 LIMIT = (__int128)1 << 64;
2064 if (a == 0 or b == 0)
2065 return 0;
2066 if (a > LIMIT / b)
2067 return LIMIT;
2068 return a * b;
2069}
2070
2071struct crt {
2072 using T = __int128;
2073 T a, m;
2074
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)
2079 return {-1, 0};
2080
2081 T g = gcd128(m, C.m);
2082 if ((C.a - a) % g != 0)
2083 return {-1, 0};
2084
2085 T m1 = m / g;
2086 T m2 = C.m / g;
2087
2088 if (m2 == 1)
2089 return {a, m};
2090
2091 T inv = modular_inverse_128(m1 % m2, m2);
2092
2093 T k = ((C.a - a) / g) % m2;
2094 if (k < 0)
2095 k += m2;
2096
2097 k = static_cast<unsigned __int128>(k) * inv % m2;
2098
2099 T lcm = mul_saturate(m, m2);
2100
2101 T res = (a + static_cast<T>((static_cast<unsigned __int128>(k) * m) %
2102 lcm)) %
2103 lcm;
2104 if (res < 0)
2105 res += lcm;
2106
2107 return {res, lcm};
2108 }
2109};
2110
2111// Math hacks to operate on log space.
2112
2113inline constexpr long double LOG_ZERO = -INFINITY;
2114inline constexpr long double LOG_ONE = 0.0;
2115
2116inline long double log_space(long double x) {
2117 return x == 0.0 ? LOG_ZERO : std::log(x);
2118}
2119
2120// Math hack to add two values in log space.
2121inline long double add_log_space(long double a, long double b) {
2122 if (a == LOG_ZERO)
2123 return b;
2124 if (b == LOG_ZERO)
2125 return a;
2126 if (a < b)
2127 std::swap(a, b);
2128 if (b == LOG_ZERO)
2129 return a;
2130 return a + log1p(exp(b - a));
2131}
2132
2133// Math hack to subtract two values in log space.
2134// a >= b.
2135inline long double sub_log_space(long double a, long double b) {
2136 if (b >= a)
2137 return LOG_ZERO;
2138 if (b == LOG_ZERO)
2139 return a;
2140 return a + log1p(-exp(b - a));
2141}
2142
2143} // namespace _detail
2144
2145// Sorted.
2146// O(n^(1/4) log n) expected.
2147// 0 < n.
2148inline std::vector<uint64_t> factor(uint64_t n) {
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());
2152 return factors;
2153}
2154
2155// Sorted.
2156// O(n^(1/4) log n) expected.
2157// 0 < n.
2158inline std::vector<std::pair<uint64_t, int>> factor_by_prime(uint64_t n) {
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;
2164 else
2165 primes.emplace_back(p, 1);
2166 }
2167 return primes;
2168}
2169
2170// O(log mod).
2171// 0 < a < mod.
2172// gcd(a, mod) = 1.
2173inline uint64_t modular_inverse(uint64_t a, uint64_t mod) {
2174 return _detail::modular_inverse_128(a, mod);
2175}
2176
2177// O(n^(1/4) log n) expected.
2178// 0 < n.
2179inline uint64_t totient(uint64_t n) {
2180 tgen_ensure(n > 0, "math: totient(0) is undefined");
2181 uint64_t phi = n;
2182
2183 for (auto [p, e] : factor_by_prime(n))
2184 phi -= phi / p;
2185
2186 return phi;
2187}
2188
2189// Returns `(p_i, g_i)`: `p_i` is the prime, `g_i` is the gap.
2190inline const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> &
2191prime_gaps() {
2192 // From https://en.wikipedia.org/wiki/Prime_gap.
2193 static const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> value{
2194 /* clang-format off */ {
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
2211 }, /* clang-format on */
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}};
2219
2220 return value;
2221}
2222
2223// Returns pair (first_composite_in_gap, last_composite_in_gap).
2224// O(log r) approximately.
2225inline std::pair<uint64_t, uint64_t> prime_gap_upto(uint64_t r) {
2226 if (r < 4)
2227 throw _detail::there_is_no_upto_error("prime gap", r);
2228
2229 const auto &[P, G] = prime_gaps();
2230 for (int i = P.size() - 1;; --i) {
2231 if (P[i] >= r)
2232 continue;
2233
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];
2237
2238 if (curr >= prev)
2239 return {P[i] + 1, right};
2240 }
2241}
2242
2243// From https://oeis.org/A002182/b002182.txt.
2245 /* clang-format off */
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}; /* clang-format on */
2280 return highly_composites;
2281}
2282
2283// O(log r) approximately.
2284inline uint64_t highly_composite_upto(uint64_t r) {
2285 for (int i = highly_composites().size() - 1; i >= 0; --i)
2286 if (highly_composites()[i] <= r)
2287 return highly_composites()[i];
2288
2289 throw _detail::there_is_no_upto_error("highly composite number", r);
2290}
2291
2292// O(log^3 r) expected.
2293// Generates a random prime in [l, r].
2294inline uint64_t gen_prime(uint64_t l, uint64_t r) {
2295 if (r < l or r < 2)
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) {
2300 // There might be no primes in the range.
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)
2305 if (is_prime(i))
2306 return i;
2307 throw _detail::there_is_no_in_range_error("prime", l, r);
2308 }
2309
2310 uint64_t n;
2311 do {
2312 n = next(l, r);
2313 } while (!is_prime(n));
2314 return n;
2315}
2316
2317// O(log^3 l) expected.
2318// l <= 2^64 - 59.
2319inline uint64_t prime_from(uint64_t l) {
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)
2323 if (is_prime(i))
2324 return i;
2325}
2326
2327// O(log^3 r) expected.
2328inline uint64_t prime_upto(uint64_t r) {
2329 if (r >= 2)
2330 for (uint64_t i = r; i >= 2; --i)
2331 if (is_prime(i))
2332 return i;
2333 throw _detail::there_is_no_upto_error("prime", r);
2334}
2335
2336// O(n^(1/4) log n) expected.
2337// 0 < n.
2338inline int num_divisors(uint64_t n) {
2339 int divisors = 1;
2340 for (auto [p, e] : factor_by_prime(n))
2341 divisors *= (e + 1);
2342 return divisors;
2343}
2344
2345// O(log(r) log(divisor_count)).
2346// divisor_count is prime.
2347inline uint64_t gen_divisor_count(uint64_t l, uint64_t r, int divisor_count) {
2348 tgen_ensure(divisor_count > 0 and is_prime(divisor_count),
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);
2354}
2355
2356// O(|mods| + log r).
2357// |rems| = |mods|.
2358// rems_i < mods_i.
2359inline uint64_t gen_congruent(uint64_t l, uint64_t r,
2360 std::vector<uint64_t> rems,
2361 std::vector<uint64_t> mods) {
2362 if (l > r)
2363 throw _detail::there_is_no_in_range_error("congruent number", l, r);
2364 tgen_ensure(rems.size() == mods.size(),
2365 "math: number of remainders and mods must be the same");
2366 tgen_ensure(rems.size() > 0, "math: must have at least one congruence");
2367
2368 _detail::crt crt;
2369 for (int i = 0; i < static_cast<int>(rems.size()); ++i) {
2370 tgen_ensure(rems[i] < mods[i],
2371 "math: remainder must be smaller than the mod");
2372 crt = crt * _detail::crt(rems[i], mods[i]);
2373
2374 if (crt.a == -1)
2375 throw _detail::there_is_no_in_range_error("congruent number", l, r);
2376 if (crt.m > r) {
2377 if (!(l <= crt.a and crt.a <= r))
2378 throw _detail::there_is_no_in_range_error("congruent number", l,
2379 r);
2380
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);
2385 return crt.a;
2386 }
2387 }
2388
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;
2391
2392 if (k_min > k_max)
2393 throw _detail::there_is_no_in_range_error("congruent number", l, r);
2394
2395 return crt.a + next(k_min, k_max) * crt.m;
2396}
2397
2398// O(log r).
2399// rem < mod.
2400inline uint64_t gen_congruent(uint64_t l, uint64_t r, uint64_t rem,
2401 uint64_t mod) {
2402 return gen_congruent(l, r, std::vector<uint64_t>({rem}),
2403 std::vector<uint64_t>({mod}));
2404}
2405
2406// Firsr congruent number >= l.
2407// O(|mods| + log r).
2408// |rems| = |mods|.
2409// rems_i < mods_i.
2410inline uint64_t congruent_from(uint64_t l, std::vector<uint64_t> rems,
2411 std::vector<uint64_t> mods) {
2412 tgen_ensure(rems.size() == mods.size(),
2413 "math: number of remainders and mods must be the same");
2414 tgen_ensure(rems.size() > 0, "math: must have at least one congruence");
2415
2416 _detail::crt crt;
2417 for (int i = 0; i < static_cast<int>(rems.size()); ++i) {
2418 tgen_ensure(rems[i] < mods[i],
2419 "math: remainder must be smaller than the mod");
2420 crt = crt * _detail::crt(rems[i], mods[i]);
2421
2422 if (crt.a == -1)
2423 throw _detail::there_is_no_from_error("congruent number", l);
2424 if (crt.m > std::numeric_limits<uint64_t>::max()) {
2425 if (crt.a < l)
2426 throw tgen::_detail::error(
2427 "math: congruent number does not exist or is too large");
2428
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");
2433 return crt.a;
2434 }
2435 }
2436
2437 uint64_t k = 0;
2438 if (crt.a < l)
2439 k = ((l - crt.a) + crt.m - 1) / crt.m;
2440 __int128 result = crt.a + k * crt.m;
2441
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);
2445}
2446
2447// O(log l)
2448// rem < mod.
2449inline uint64_t congruent_from(uint64_t l, uint64_t rem, uint64_t mod) {
2450 return congruent_from(l, std::vector<uint64_t>{rem},
2451 std::vector<uint64_t>{mod});
2452}
2453
2454// First congruent number <= r.
2455// O(|mods| + log r).
2456// |rems| = |mods|.
2457// rems_i < mods_i.
2458inline uint64_t congruent_upto(uint64_t r, std::vector<uint64_t> rems,
2459 std::vector<uint64_t> mods) {
2460 tgen_ensure(rems.size() == mods.size(),
2461 "math: number of remainders and mods must be the same");
2462 tgen_ensure(rems.size() > 0, "math: must have at least one congruence");
2463
2464 _detail::crt crt;
2465 for (int i = 0; i < static_cast<int>(rems.size()); ++i) {
2466 tgen_ensure(rems[i] < mods[i],
2467 "math: remainder must be smaller than the mod");
2468
2469 crt = crt * _detail::crt(rems[i], mods[i]);
2470
2471 if (crt.a == -1)
2472 throw _detail::there_is_no_upto_error("congruent number", r);
2473 if (crt.m > r) {
2474 if (!(crt.a <= r))
2475 throw _detail::there_is_no_upto_error("congruent number", r);
2476
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",
2480 r);
2481 return crt.a;
2482 }
2483 }
2484
2485 if (crt.a > r)
2486 throw _detail::there_is_no_upto_error("congruent number", r);
2487
2488 uint64_t k = (r - crt.a) / crt.m;
2489 __int128 result = crt.a + k * crt.m;
2490
2491 if (result < 0)
2492 throw _detail::there_is_no_upto_error("congruent number", r);
2493 return static_cast<uint64_t>(result);
2494}
2495
2496// O(log r)
2497// rem < mod.
2498inline uint64_t congruent_upto(uint64_t r, uint64_t rem, uint64_t mod) {
2499 return congruent_upto(r, std::vector<uint64_t>{rem},
2500 std::vector<uint64_t>{mod});
2501}
2502
2503// Mod used for FFT/NTT.
2504inline constexpr int FFT_MOD = 998244353;
2505
2506// Fibonacci sequence up to 2^64.
2507inline const std::vector<uint64_t> &fibonacci() {
2508 static const std::vector<uint64_t> fib = [] {
2509 std::vector<uint64_t> v = {0, 1};
2510 while (v.back() <=
2511 std::numeric_limits<uint64_t>::max() - v[v.size() - 2])
2512 v.push_back(v.back() + v[v.size() - 2]);
2513 return v;
2514 }();
2515 return fib;
2516}
2517
2518// Parition is ordered (composition), that is, (1, 1, 2) != (1, 2, 1).
2519// O(n).
2520// 0 < n.
2521// 0 < part_l.
2522inline std::vector<int>
2523gen_partition(int n, int part_l = 1, std::optional<int> part_r = std::nullopt) {
2524 if (!part_r)
2525 part_r = n;
2526 part_r = std::min(*part_r, n);
2527 tgen_ensure(n > 0 and part_l > 0,
2528 "math: invalid parameters to gen_partition");
2529 tgen_ensure(part_l <= n and *part_r > 0, "math: no such partition");
2530
2531 // dp[i] = log(numbers of ways to add to i).
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) {
2536 if (i >= part_l)
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]);
2540 dp[i] = window;
2541 }
2542 tgen_ensure(dp[n] >= 0, "math: no such partition");
2543
2544 // Crazy math tricks ahead.
2545 auto dp_pref = dp;
2546 for (int i = 1; i <= n; ++i)
2547 dp_pref[i] = _detail::add_log_space(dp_pref[i - 1], dp[i]);
2548
2549 std::vector<int> part;
2550 int sum = n;
2551 while (sum > 0) {
2552 // Will generate a number such that what remains is in [l, r].
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");
2556
2557 int nxt_sum = std::min(sum, r);
2558 long double random = next<long double>(0, 1);
2559
2560 // We generate a value X (log space), and then choose nxt_sum such
2561 // that dp_pref[nxt_sum-1] < X <= dp_pref[nxt_sum].
2562
2563 // Math hack:
2564 // Let A = pref[l-1], B = pref[r], U = rand().
2565 // X = log[exp(A) + U * (exp(B) - exp(A))]
2566 // = log{exp(B) * [exp(A) / exp(B) + U * (1 - exp(A) / exp(B))]}
2567 // = B + log[exp(A - B) + U - U * exp(A - B))]
2568 // = B + log[U + (1 - U) * exp(A - B)].
2569 long double val_l = l ? dp_pref[l - 1] : _detail::LOG_ZERO,
2570 val_r = dp_pref[r];
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)))
2575 --nxt_sum;
2576
2577 part.push_back(sum - nxt_sum);
2578 sum = nxt_sum;
2579 }
2580
2581 return part;
2582}
2583
2584// Parition is ordered (composition), that is, (1, 1, 2) != (1, 2, 1).
2585// O(n) time/memory if part_r is not set, O(n * k) time/memory otherwise.
2586// 0 < k <= n.
2587// 0 <= part_l.
2588inline std::vector<int>
2589gen_partition_fixed_size(int n, int k, int part_l = 0,
2590 std::optional<int> part_r = std::nullopt) {
2591 if (!part_r)
2592 part_r = n;
2593 part_r = std::min(*part_r, n);
2594 tgen_ensure(0 < k and k <= n and part_l >= 0,
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");
2599
2600 // What we need to distribute to the parts.
2601 int s = n - k * part_l;
2602
2603 std::vector<int> part(k);
2604 if (*part_r == n) {
2605 // Stars and bars - O(n).
2606 std::vector<int> cuts = {-1};
2607
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)) {
2612 cuts.push_back(i);
2613 --bars;
2614 }
2615 cuts.push_back(total);
2616
2617 // Recovers parts.
2618 for (int i = 0; i < k; ++i)
2619 part[i] = cuts[i + 1] - cuts[i] - 1;
2620 } else {
2621 // DP with log trick - O(nk).
2622 int u = *part_r - part_l;
2623
2624 // dp[i][j] = log(#ways to fill i parts with sum j)
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;
2628
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]);
2633
2634 for (int j = 0; j <= s; ++j) {
2635 dp[i][j] = pref[j];
2636 if (j >= u + 1)
2637 dp[i][j] =
2638 _detail::sub_log_space(dp[i][j], pref[j - u - 1]);
2639 }
2640 }
2641
2642 // Recovers parts backwards.
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");
2652
2653 // Now we choose a number with probability proportional to
2654 // dp[i-1][.].
2655
2656 // log(rand() * total) = log(rand()) + log(total).
2657 long double random =
2658 _detail::log_space(next<long double>(0, 1)) + log_total;
2659
2660 long double cur_prob = _detail::LOG_ZERO;
2661 int chosen = 0;
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) {
2666 chosen = j;
2667 break;
2668 }
2669 }
2670
2671 part[k - i] = chosen;
2672 left_to_distribute -= chosen;
2673 }
2674 }
2675
2676 for (int &i : part)
2677 i += part_l;
2678 return part;
2679}
2680
2681}; // namespace math
2682
2683/**************
2684 * *
2685 * STRING *
2686 * *
2687 **************/
2688
2689/*
2690 * String generator.
2691 */
2692
2693namespace _detail {
2694
2695/*
2696 * Regex.
2697 *
2698 * Compatible with testlib's regex.
2699 *
2700 * Operations:
2701 * - A single character yields itself ("a", "3").
2702 * - A list of characters inside square braces yields any a random element
2703 * from the list ("[abc123]").
2704 * - A range of characters is equivalent to listing them ("[a-z1-9A-Z]").
2705 * - A pattern followed by {n} yields the pattern repeated n times ("a{3}").
2706 * - A pattern followed by {l,r} yields the pattern repeated between l and r
2707 * times, uniformly at random ("a{3,5}").
2708 * - A list of patterns separated by | yields a random pattern from the
2709 * list, uniformly at random ("abc|def|ghi").
2710 * - Parentheses can be used for grouping ("a((a|b){3})").
2711 *
2712 * Examples:
2713 * 1. str("[1-9][0-9]{1,2}") generates two- or three-digit numbers.
2714 * 2. str("a[b-d]{2}|e") generates "e" or a random string of length 3, with
2715 * the first character being 'a' and the second and
2716 * third characters being 'b', 'c', or 'd'.
2717 * 3. str("[1-9][0-9]{%d}", n-1) generates n-digit numbers.
2718 *
2719 * Operations defined by {n} and {l,r} are applied from left to right, and
2720 * the pattern that comes before has its delimiters defined either by () or
2721 * [] at its end or is taken from the beginning of the pattern (in
2722 * "a[bc]{2}", "{2}" is applied to "[bc]", and in "[01]abc{3}", the "{3}" is
2723 * appied to "[01]abc").
2724 */
2725
2726// If it has children, it is either a SEQ or an OR group, defined by the
2727// pattern_ field.
2728struct regex_node {
2729 // Considered to be repetition of left_bound != -1, pattern if
2730 // children_.empty(), otherwise "SEQ" or "OR", defined by the pattern_
2731 // field.
2732 std::string
2733 pattern_; // Either pattern, or "SEQ" or "OR" (if !children_.empty()).
2734 std::vector<regex_node> children_; // Children, when SEQ or OR.
2735 int left_bound_, right_bound_; // Left and right bounds of the repetition,
2736 // or -1 if not a repetition.
2737 double
2738 log_space_num_ways_; // Log space number of ways to match the pattern.
2739 std::optional<unique_container<char>>
2740 distinct_; // Distinct generator for the pattern, for [chars].
2741
2742 // c or [chars].
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;
2747 return;
2748 }
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));
2754 }
2755 // SEQ or OR.
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") {
2759 // Multiply the number of ways.
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") {
2764 // Add the number of ways.
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_);
2769 } else
2770 tgen_ensure_against_bug("str: invalid regex: expected SEQ or OR");
2771
2772 children_ = std::move(children);
2773 children.clear();
2774 }
2775 // REP.
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_);
2782
2783 children_.push_back(std::move(child));
2784 }
2785};
2786
2787// State of the regex parser.
2788struct regex_state {
2789 std::vector<regex_node> cur; // Current sequence of nodes.
2790 std::vector<regex_node> branches; // Branches of the current OR group.
2791};
2792
2793// Creates a SEQ node from the current state.
2794inline regex_node make_regex_seq(regex_state &st) {
2795 return regex_node("SEQ", st.cur);
2796}
2797
2798// Finishes current state.
2799inline regex_node finish_regex_state(regex_state &st) {
2800 // SEQ.
2801 if (st.branches.empty())
2802 return make_regex_seq(st);
2803
2804 // OR.
2805 st.branches.push_back(make_regex_seq(st));
2806 return regex_node("OR", st.branches);
2807}
2808
2809// Parses a regex pattern into a tree, computing the number of ways to match the
2810// pattern.
2811inline regex_node parse_regex(std::string regex) {
2812 std::string new_regex;
2813 for (char c : regex)
2814 if (c != ' ')
2815 new_regex += c;
2816 swap(regex, new_regex);
2817 regex_state cur;
2818 std::vector<regex_state> stack;
2819
2820 for (size_t i = 0; i < regex.size(); i++) {
2821 char c = regex[i];
2822
2823 if (c == '(') {
2824 // Pushes the current state to the stack.
2825 stack.push_back(std::move(cur));
2826 cur = regex_state();
2827 } else if (c == ')') {
2828 // Finishes the current state, and adds it to the parent.
2829 regex_node node = finish_regex_state(cur);
2830
2831 tgen_ensure(!stack.empty(), "str: invalid regex: unmatched `)`");
2832 cur = std::move(stack.back());
2833 stack.pop_back();
2834
2835 cur.cur.push_back(std::move(node));
2836 } else if (c == '|') {
2837 // Starts a new OR group.
2838 regex_node node = make_regex_seq(cur);
2839 cur.branches.push_back(std::move(node));
2840 } else if (c == '[') {
2841 // Parses a character class.
2842 std::string chars;
2843
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];
2847 if (a > b)
2848 std::swap(a, b);
2849 for (char x = a; x <= b; x++)
2850 chars += x;
2851 i += 2;
2852 } else
2853 chars += regex[i];
2854 }
2855
2856 tgen_ensure(i < regex.size() and regex[i] == ']',
2857 "str: invalid regex: unmatched `[`");
2858 cur.cur.emplace_back("[" + chars + "]");
2859 } else if (c == '{') {
2860 // Parses a repetition.
2861 ++i;
2862 int l = -1, r = -1;
2863
2864 while (i < regex.size() and
2865 isdigit(static_cast<unsigned char>(regex[i]))) {
2866 if (l == -1)
2867 l = 0;
2868 tgen_ensure(l <= static_cast<int>(1e8),
2869 "str: invalid regex: number too large inside `{}`");
2870 l = 10 * l + (regex[i] - '0');
2871 ++i;
2872 }
2873
2874 if (i < regex.size() and regex[i] == ',') {
2875 ++i;
2876 while (i < regex.size() and
2877 isdigit(static_cast<unsigned char>(regex[i]))) {
2878 if (r == -1)
2879 r = 0;
2881 r <= static_cast<int>(1e8),
2882 "str: invalid regex: number too large inside `{}`");
2883 r = 10 * r + (regex[i] - '0');
2884 ++i;
2885 }
2886 } else
2887 r = l;
2888
2889 tgen_ensure(i < regex.size() and regex[i] == '}',
2890 "str: invalid regex: unmatched `{`");
2891 tgen_ensure(l != -1 and r != -1,
2892 "str: invalid regex: missing number inside `{}`");
2893 tgen_ensure(l <= r, "invalid regex: invalid range inside `{}`");
2894
2895 // Creates a REP node from the previous node.
2896 tgen_ensure(!cur.cur.empty(),
2897 "str: invalid regex: expected expression before `{}`");
2898
2899 regex_node rep(l, r, cur.cur.back());
2900 cur.cur.pop_back();
2901 cur.cur.push_back(std::move(rep));
2902 } else {
2903 // Creates a char node.
2904 cur.cur.emplace_back(std::string(1, c));
2905 }
2906 }
2907
2908 tgen_ensure(stack.empty(), "str: invalid regex: unmatched `(`");
2909 return finish_regex_state(cur);
2910}
2911
2912// Generates a uniformly random string that matches the given regex.
2913inline void gen_regex(const regex_node &node, std::string &str) {
2914 // For [chars], generate a random character from the list.
2915 if (node.pattern_[0] == '[') {
2916 str += node.pattern_[1 + next<int>(0, node.pattern_.size() - 3)];
2917 return;
2918 }
2919
2920 // For REP, generate a random number of times to repeat the pattern.
2921 if (node.left_bound_ != -1) {
2922 // Generates a random value W from 0 to num_ways.
2923 // log(W) = log(random(0, 1) * num_ways)
2924 // = log(random(0, 1)) + log(num_ways).
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_;
2929
2930 for (int i = node.left_bound_; i <= node.right_bound_; ++i) {
2931 cur_prob =
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);
2936 return;
2937 }
2938 }
2939
2940 tgen_ensure_against_bug(false,
2941 "str: log_rand > cur_prob in REP gen_regex");
2942 }
2943
2944 // For SEQ, generate all children.
2945 if (!node.children_.empty() and node.pattern_ == "SEQ") {
2946 for (const regex_node &child : node.children_)
2947 gen_regex(child, str);
2948 return;
2949 }
2950
2951 // For OR, generate a random child.
2952 if (!node.children_.empty() and node.pattern_ == "OR") {
2953 // Generates a random value W from 0 to num_ways.
2954 // log(W) = log(random(0, 1) * num_ways)
2955 // = log(random(0, 1)) + log(num_ways).
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;
2959
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);
2965 return;
2966 }
2967 }
2968
2969 tgen_ensure_against_bug(false,
2970 "str: log_rand > cur_prob in OR gen_regex");
2971 }
2972
2973 // For char, generate the character.
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];
2979}
2980
2981// Formats a regex string with given arguments.
2982template <typename... Args>
2983std::string regex_format(const std::string &s, Args &&...args) {
2984 if constexpr (sizeof...(Args) == 0) {
2985 return s;
2986 } else {
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...);
2990 buf.pop_back(); // remove '\0'
2991 return buf;
2992 }
2993}
2994
2995// Computes polynomial hash of a string.
2996// O(|s|).
2997inline int hash_string(const std::string &s, int base, int mod) {
2998 long long h = 0;
2999 for (char c : s)
3000 h = (h * base + c - 'a' + 1) % mod;
3001 return h;
3002}
3003
3004// Estimates the length of the string to very likely have a collision.
3005inline int estimate_length(int alphabet_size, int mod) {
3006 // Magic constants.
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);
3010
3011 return static_cast<int>(std::ceil(adjusted));
3012}
3013
3014// Collides two strings to have the same polynomial hash.
3015// O(sqrt(mod) log(mod)) with high probability.
3016inline std::pair<std::string, std::string>
3017birthday_attack(const std::vector<std::string> &alphabet, int base, int mod) {
3018 tgen_ensure(0 < base and base < 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);
3022
3023 while (true) {
3024 std::vector<int> seq(length);
3025
3026 std::string s;
3027 s.reserve(length * alphabet[0].size());
3028
3029 for (int i = 0; i < length; i++) {
3030 seq[i] = next<int>(0, alphabet.size() - 1);
3031 s += alphabet[seq[i]];
3032 }
3033
3034 int h = hash_string(s, base, mod);
3035
3036 auto it = seen.find(h);
3037 if (it != seen.end() and it->second != seq) {
3038 std::string a, b;
3039
3040 for (int x : it->second)
3041 a += alphabet[x];
3042 for (int x : seq)
3043 b += alphabet[x];
3044
3045 if (a != b)
3046 return {a, b};
3047 }
3048
3049 seen[h] = seq;
3050 }
3051}
3052
3053} // namespace _detail
3054
3055struct str : gen_base<str> {
3056 std::optional<sequence<char>> seq_; // Sequence of characters.
3057 std::optional<_detail::regex_node>
3058 root_; // Root node of the regex tree for the whole string.
3059
3060 // Creates generator for strings of size 'size', with random characters in
3061 // [value_l, value_r].
3062 str(int size, char value_l = 'a', char value_r = 'z')
3063 : seq_(sequence<char>(size, value_l, value_r)) {}
3064
3065 // Creates generator for strings of size 'size', with random characters in
3066 // 'chars'.
3067 str(int size, std::set<char> chars) : seq_(sequence<char>(size, chars)) {}
3068
3069 // Creates generator for strings that match the given regex.
3070 template <typename... Args> str(const std::string &regex, Args &&...args) {
3071 tgen_ensure(regex.size() > 0, "str: regex must be non-empty");
3072
3073 root_ = _detail::parse_regex(
3074 _detail::regex_format(regex, std::forward<Args>(args)...));
3075 }
3076
3077 // Restricts strings for str[idx] = value.
3078 str &fix(int idx, char character) {
3079 tgen_ensure(!root_, "str: cannot add restriction for regex");
3080 seq_->fix(idx, character);
3081 return *this;
3082 }
3083
3084 // Restricts strings for str[idx_1] = str[idx_2].
3085 str &equal(int idx_1, int idx_2) {
3086 tgen_ensure(!root_, "str: cannot add restriction for regex");
3087 seq_->equal(idx_1, idx_2);
3088 return *this;
3089 }
3090
3091 // Restricts strings for str[left..right] to have all equal values.
3092 str &equal_range(int left, int right) {
3093 tgen_ensure(!root_, "str: cannot add restriction for regex");
3094 seq_->equal_range(left, right);
3095 return *this;
3096 }
3097
3098 // Restricts strings for str[left..right] to be a palindrome.
3099 str &palindrome(int left, int 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)
3104 equal(i, right - (i - left));
3105 return *this;
3106 }
3107
3108 // Restricts strings for the entire string to be a palindrome.
3110 tgen_ensure(!root_, "str: cannot add restriction for regex");
3111 return palindrome(0, seq_->size_ - 1);
3112 }
3113
3114 // Restricts strings for str[S] to be distinct, for given subset S of
3115 // indices.
3116 str &distinct(std::set<int> indices) {
3117 tgen_ensure(!root_, "str: cannot add restriction for regex");
3118 seq_->distinct(indices);
3119 return *this;
3120 }
3121
3122 // Restricts strings for str[idx_1] != str[idx_2].
3123 str &different(int idx_1, int idx_2) {
3124 tgen_ensure(!root_, "str: cannot add restriction for regex");
3125 seq_->different(idx_1, idx_2);
3126 return *this;
3127 }
3128
3129 // Restricts strings for all values to be distinct.
3131 tgen_ensure(!root_, "str: cannot add restriction for regex");
3132 seq_->distinct();
3133 return *this;
3134 }
3135
3136 // str instance.
3137 // Operations on an instance are not random.
3139 using tgen_is_sequential_tag = _detail::is_sequential_tag;
3140 using tgen_has_subset_defined_tag = _detail::has_subset_defined_tag;
3141
3142 using value_type = char;
3143 using std_type = std::string;
3144 std::string str_;
3145
3146 instance(const std::string &str) : str_(str) {
3147 tgen_ensure(!str_.empty(), "str: instance: cannot be empty");
3148 }
3149
3150 // Fetches size.
3151 int size() const { return str_.size(); }
3152
3153 // Fetches position idx.
3154 char &operator[](int idx) {
3155 tgen_ensure(0 <= idx and idx < size(),
3156 "str: instane: index out of bounds");
3157 return str_[idx];
3158 }
3159 const char &operator[](int idx) const {
3160 tgen_ensure(0 <= idx and idx < size(),
3161 "str: instance: index out of bounds");
3162 return str_[idx];
3163 }
3164
3165 // Sorts characters in non-decreasing order.
3166 // O(n log n).
3168 std::sort(str_.begin(), str_.end());
3169 return *this;
3170 }
3171
3172 // Reverses string.
3173 // O(n).
3175 std::reverse(str_.begin(), str_.end());
3176 return *this;
3177 }
3178
3179 // Lowercases all characters.
3180 // O(n).
3182 for (char &c : str_)
3183 c = std::tolower(c);
3184 return *this;
3185 }
3186
3187 // Uppercases all characters.
3188 // O(n).
3190 for (char &c : str_)
3191 c = std::toupper(c);
3192 return *this;
3193 }
3194
3195 // Concatenates two instances.
3196 // Linear.
3198 return instance(str_ + rhs.str_);
3199 }
3200
3201 // Prints to std::ostream, separated by spaces.
3202 friend std::ostream &operator<<(std::ostream &out,
3203 const instance &inst) {
3204 return out << inst.str_;
3205 }
3206
3207 // Gets a std::string representing the instance.
3208 std::string to_std() const { return str_; }
3209 };
3210
3211 // Generates str instance.
3212 // If created from restrictions: O(n log n).
3213 // If created from regex: expected linear.
3214 instance gen() const {
3215 if (root_) {
3216 // Regex.
3217 std::string ret_str;
3218 gen_regex(*root_, ret_str);
3219 return instance(ret_str);
3220 } else {
3221 // Sequence.
3222 std::vector<char> vec = seq_->gen().to_std();
3223 return instance(std::string(vec.begin(), vec.end()));
3224 }
3225 }
3226
3227 // Fetches prefix of length n of the string "abacabadabacabae...".
3228 // O(n).
3229 static instance abacaba(int n) {
3230 tgen_ensure(n > 0, "str: size must be positive");
3231 std::string str = "a";
3232 char c = 'a';
3233 while (static_cast<int>(str.size()) < n) {
3234 int prev_size = str.size();
3235 str += ++c;
3236 for (int j = 0; j < prev_size and static_cast<int>(str.size()) < n;
3237 ++j)
3238 str += str[j];
3239 }
3240 return instance(str);
3241 }
3242
3243 // Two strings that have same polynomial hash for any base, for
3244 // mod = power of 2 up to 2^64.
3245 // Thue–Morse.
3246 // O(1).
3248 std::string a, b;
3249 int size = 1 << 10;
3250 for (int i = 0; i < size; ++i) {
3251 a += 'a' + math::_detail::popcount(i) % 2;
3252 b += 'a' + ('b' - a[i]);
3253 }
3254 return {instance(a), instance(b)};
3255 }
3256
3257 // Collides two strings to have the same polynomial hash.
3258 // O(sqrt(mod) log(mod)) with high probability.
3259 // 0 < base < mod.
3260 static std::pair<instance, instance>
3261 polynomial_hash_hack(int alphabet_size, int base, int mod) {
3262 tgen_ensure(alphabet_size > 1,
3263 "str: alphabet size must be greater than 1");
3264 tgen_ensure(0 < base and base < mod, "str: base must be in (0, mod)");
3265
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);
3271 }
3272
3273 // Collides two strings to have the same polynomial hash for multiple bases
3274 // and mods (up to 2 pairs).
3275 // O(sqrt(mod) log^2 (mod)) with high probability,
3276 // with mod = max(mod_1, mod_2).
3277 static std::pair<instance, instance>
3278 polynomial_hash_hack(int alphabet_size, std::vector<int> bases,
3279 std::vector<int> mods) {
3280 tgen_ensure(bases.size() == mods.size(),
3281 "str: bases and mods must have the same size");
3282 tgen_ensure(bases.size() > 0,
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");
3286
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)
3292 return {S1, T1};
3293 return _detail::birthday_attack({S1, T1}, bases[1], mods[1]);
3294 }
3295};
3296
3297/*********************
3298 * *
3299 * MISCELLANEOUS *
3300 * *
3301 *********************/
3302
3303namespace misc {
3304
3305namespace _detail {
3306
3307// Tried to find correct multipliers for unordered_map/set to force
3308// collisions. O(1).
3309inline std::set<long long> get_hash_hack_multipliers() {
3310 std::set<long long> multipliers = {85229};
3311
3312 // Codeforces GCC GNU G++17 7.3.0 case.
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);
3324
3325 return multipliers;
3326}
3327
3328} // namespace _detail
3329
3330// Returns a list of integers for unordered_map/set to force collisions.
3331// O(size).
3332inline std::vector<long long> unordered_hack(int size) {
3333 tgen_ensure(size > 0, "misc: unordered_hack: size must be positive");
3334 std::set<long long> multipliers = _detail::get_hash_hack_multipliers();
3335 long long mult = 1;
3336 std::set<long long>::iterator it = multipliers.begin();
3337
3338 std::vector<long long> list;
3339 while (static_cast<int>(list.size()) < size) {
3340 list.push_back(mult * (*it));
3341 ++it;
3342 if (it == multipliers.end()) {
3343 it = multipliers.begin();
3344 ++mult;
3345 }
3346 }
3347 return list;
3348}
3349
3350// Generates a random balanced parentheses sequence with k '(' and k ')'.
3351// Valid meanst that for no prefix there are more ')' than '('.
3352// O(size).
3353inline std::string gen_parenthesis(int size) {
3354 tgen_ensure(size > 0 and size % 2 == 0,
3355 "misc: parenthesis: size must a positive even number");
3356
3357 int k = size / 2;
3358 std::string s;
3359 int open = 0, close = 0;
3360
3361 for (int i = 0; i < size; ++i) {
3362 if (open == k) {
3363 s += ')';
3364 ++close;
3365 continue;
3366 }
3367 if (open == close) {
3368 s += '(';
3369 ++open;
3370 continue;
3371 }
3372
3373 long long a = k - open, b = k - close, h = open - close;
3374
3375 // Probability of placing '(':
3376 // P('(') = (k - open) * (bal + 1) / (rem)
3377 // Derived from ballot numbers ratio.
3378 long long num = a * (h + 2);
3379 long long den = (a + b) * (h + 1);
3380
3381 if (next<long long>(1, den) <= num) {
3382 s += '(';
3383 ++open;
3384 } else {
3385 s += ')';
3386 ++close;
3387 }
3388 }
3389
3390 return s;
3391}
3392
3393} // namespace misc
3394
3395} // namespace tgen
C::value_type any(const C &container)
Choses a random element from container.
Definition tgen.h:635
C shuffled(const C &container)
Shuffles a container.
Definition tgen.h:597
void shuffle(It first, It last)
Shuffles range inplace, for random_access_iterator.
Definition tgen.h:576
T next(T n)
Returns a random number up to value.
Definition tgen.h:528
size_t next_by_distribution(const std::vector< T > &distribution)
Returns random index with given probabilities.
Definition tgen.h:557
It::value_type any(It first, It last)
Choses a random element from iterator range.
Definition tgen.h:624
T next(T l, T r)
Returns a random number in range.
Definition tgen.h:543
#define tgen_ensure(cond,...)
Ensures condition is true.
Definition tgen.h:95
C choose(int k, const C &container)
Chooses elements from container, as in a subsequence fixed length.
Definition tgen.h:702
C::value_type any_by_distribution(const C &container, std::vector< T > distribution)
Choses a random element with given probabilities.
Definition tgen.h:653
Inst::value_type any_by_distribution(const Inst &inst, const std::vector< T > &distribution)
Choses a random element from the sequence instance.
Definition tgen.h:685
void shuffle(Inst &inst)
Shuffles a sequence instance.
Definition tgen.h:587
uint64_t congruent_from(uint64_t l, uint64_t rem, uint64_t mod)
Computes smallest congruent from given value.
Definition tgen.h:2449
uint64_t congruent_upto(uint64_t r, uint64_t rem, uint64_t mod)
Computes largest congruent up to given value.
Definition tgen.h:2498
uint64_t congruent_from(uint64_t l, std::vector< uint64_t > rems, std::vector< uint64_t > mods)
Computes smallest congruent from given value.
Definition tgen.h:2410
std::pair< uint64_t, uint64_t > prime_gap_upto(uint64_t r)
Largest prime gap up to given number.
Definition tgen.h:2225
uint64_t prime_upto(uint64_t r)
Computes largest prime up to given value.
Definition tgen.h:2328
uint64_t totient(uint64_t n)
Euler's totient function.
Definition tgen.h:2179
uint64_t prime_from(uint64_t l)
Computes smallest prime from given value.
Definition tgen.h:2319
std::vector< uint64_t > factor(uint64_t n)
Factors a number into primes.
Definition tgen.h:2148
int num_divisors(uint64_t n)
Computes the number of divisors of a given number.
Definition tgen.h:2338
bool is_prime(uint64_t n)
Checks if a number is prime.
Definition tgen.h:1885
uint64_t gen_prime(uint64_t l, uint64_t r)
Generates a random prime in given range.
Definition tgen.h:2294
constexpr int FFT_MOD
FFT/NTT mod.
Definition tgen.h:2504
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.
Definition tgen.h:2400
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.
Definition tgen.h:2359
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.
Definition tgen.h:2589
uint64_t highly_composite_upto(uint64_t r)
Largest highly composite number up to given number.
Definition tgen.h:2284
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.
Definition tgen.h:2523
std::vector< std::pair< uint64_t, int > > factor_by_prime(uint64_t n)
Factors a number into primes and its powers.
Definition tgen.h:2158
const std::vector< uint64_t > & fibonacci()
Fetches Fibonacci numbers.
Definition tgen.h:2507
uint64_t modular_inverse(uint64_t a, uint64_t mod)
Computes modular inverse.
Definition tgen.h:2173
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.
Definition tgen.h:2347
const std::vector< uint64_t > & highly_composites()
Fetches highly composite numbers.
Definition tgen.h:2244
uint64_t congruent_upto(uint64_t r, std::vector< uint64_t > rems, std::vector< uint64_t > mods)
Computes largest congruent up to given value.
Definition tgen.h:2458
std::string gen_parenthesis(int size)
Generates a random valid parenthesis sequence.
Definition tgen.h:3353
std::vector< long long > unordered_hack(int size)
List of integers that force collision on stdunordered_set.
Definition tgen.h:3332
T opt(const std::string &key, std::optional< T > default_value=std::nullopt)
Gets opt by key.
Definition tgen.h:1091
void set_compiler(_detail::compiler_value compiler)
Sets compiler.
Definition tgen.h:877
T opt(size_t index, std::optional< T > default_value=std::nullopt)
Gets opt by key.
Definition tgen.h:1077
bool has_opt(std::size_t index)
Checks if opt at some index exists.
Definition tgen.h:1063
bool has_opt(const std::string &key)
Checks if opt with with some key exists.
Definition tgen.h:1069
void set_cpp_version(int version)
Sets C++ version.
Definition tgen.h:858
void register_gen(std::optional< long long > seed=std::nullopt)
Sets up the generator without arguments.
Definition tgen.h:1113
void register_gen(int argc, char **argv)
Sets up the generator.
Definition tgen.h:1102
Base class for generators (should not be instantiated).
Definition tgen.h:320
auto gen_list(int size, Args &&...args) const
Generates a list of several generation calls.
Definition tgen.h:323
auto unique(Args &&...args) const
Creates unique generator for current generator.
Definition tgen.h:354
auto gen_until(Pred predicate, int max_tries, Args &&...args) const
Generates a random instance from the valid set until a condition is met.
Definition tgen.h:335
Base class for generator instances (should not be instantiated).
Definition tgen.h:377
bool operator<(const Inst &rhs) const
Definition tgen.h:380
If type is defined for a subset of itself, for tgen generator instance.
Definition tgen.h:412
If type is associative container.
Definition tgen.h:391
If type is a tgen generator instance.
Definition tgen.h:400
If type is a sequence-like tgen generator instance.
Definition tgen.h:404
Permutation instance.
Definition tgen.h:1674
instance(const std::vector< int > &vec)
Creates a permutation instance from a std::vector.
Definition tgen.h:1682
std::vector< int > to_std() const
Converts the instance to a std::vector.
Definition tgen.h:1778
const int & operator[](int idx) const
Returns the value at some position of the instance.
Definition tgen.h:1705
int size() const
Returns the size of the permutation instance.
Definition tgen.h:1702
instance & reverse()
Reverses the instance.
Definition tgen.h:1737
instance & add_1()
Adds 1 for printing.
Definition tgen.h:1761
instance & separator(char sep)
Sets separator for printing.
Definition tgen.h:1754
instance & sort()
Sorts the instance in non-decreasing order.
Definition tgen.h:1729
instance & inverse()
Inverse of the permutation.
Definition tgen.h:1744
int parity() const
Parity of the permutation.
Definition tgen.h:1713
Permutation generator.
Definition tgen.h:1642
permutation & cycles(const std::vector< int > &cycle_sizes)
Restricts generator s.t. cycle sizes are fixed.
Definition tgen.h:1661
instance gen() const
Generates a random instance from the set of valid permutations.
Definition tgen.h:1783
permutation(int size)
Creates permutation generator defined by size.
Definition tgen.h:1648
permutation & fix(int idx, int value)
Restricts generator s.t. value at index is fixed.
Definition tgen.h:1653
Printer helper for standard types.
Definition tgen.h:423
print(const T &val, char sep=' ')
Cretes a printer object.
Definition tgen.h:426
Printer helper for standard types, printing on a new line.
Definition tgen.h:506
println(const T &val, char sep=' ')
Cretes a printer object that prints on a new line.
Definition tgen.h:508
Sequence instance.
Definition tgen.h:1242
instance & reverse()
Reverses the instance.
Definition tgen.h:1279
instance operator+(const instance &rhs)
Concatenates two instances.
Definition tgen.h:1293
instance(const std::vector< T > &vec)
Creates a sequence instance from a std::vector.
Definition tgen.h:1251
T & operator[](int idx)
Accesses the value at some position of the instance.
Definition tgen.h:1259
int size() const
Returns the size of the sequence instance.
Definition tgen.h:1256
instance & separator(char sep)
Sets separator for printing.
Definition tgen.h:1286
instance & sort()
Sorts the instance in non-decreasing order.
Definition tgen.h:1272
std::vector< T > to_std() const
Converts the instance to a std::vector.
Definition tgen.h:1312
Sequence generator.
Definition tgen.h:1135
sequence(int size, std::set< T > values)
Creates sequence generator define by value set.
Definition tgen.h:1159
sequence & distinct(std::set< int > indices)
Restricts generator s.t. all values in index set are distinct.
Definition tgen.h:1221
sequence & different(int idx_1, int idx_2)
Restricts generator s.t. values at two indices are different.
Definition tgen.h:1228
sequence & fix(int idx, T value)
Restricts generator s.t. value at index is fixed.
Definition tgen.h:1172
sequence & distinct()
Restricts generator s.t. all values are distinct.
Definition tgen.h:1234
instance gen() const
Generates a random instance from the set of valid sequences.
Definition tgen.h:1367
sequence & equal_range(int left, int right)
Restricts generator s.t. all values at index range are the same.
Definition tgen.h:1210
sequence & equal(int idx_1, int idx_2)
Restricts generator s.t. values at two indices are the same.
Definition tgen.h:1197
sequence(int size, T value_l, T value_r)
Creates sequence generator define by size and range of values.
Definition tgen.h:1149
String instance.
Definition tgen.h:3138
instance & uppercase()
Sets all characters to uppercase.
Definition tgen.h:3189
std::string to_std() const
Converts the instance to a std::string.
Definition tgen.h:3208
instance & reverse()
Reverses the instance.
Definition tgen.h:3174
instance & sort()
Sorts the characters in non-decreasing order.
Definition tgen.h:3167
instance operator+(const instance &rhs)
Concatenates two instances.
Definition tgen.h:3197
instance & lowercase()
Sets all characters to lowercase.
Definition tgen.h:3181
instance(const std::string &str)
Creates a string instance from a std::string.
Definition tgen.h:3146
char & operator[](int idx)
Accesses the character at some position of the instance.
Definition tgen.h:3154
int size() const
Returns the size of the string instance.
Definition tgen.h:3151
String generator.
Definition tgen.h:3055
str & distinct()
Restricts generator s.t. all characters are distinct.
Definition tgen.h:3130
str & different(int idx_1, int idx_2)
Restricts generator s.t. characters at two indices are different.
Definition tgen.h:3123
instance gen() const
Generates a random instance from the set of valid strings.
Definition tgen.h:3214
str & palindrome(int left, int right)
Restricts generator s.t. range is a palindrome.
Definition tgen.h:3099
str & distinct(std::set< int > indices)
Restricts generator s.t. all characters in index set are distinct.
Definition tgen.h:3116
str(const std::string &regex, Args &&...args)
Creates string generator define by regex.
Definition tgen.h:3070
static std::pair< instance, instance > unsigned_polynomial_hash_hack()
Returns two strings that force polynomial hash collision for power-of-two mod.
Definition tgen.h:3247
str & equal(int idx_1, int idx_2)
Restricts generator s.t. values at two indices are the same.
Definition tgen.h:3085
str(int size, char value_l='a', char value_r='z')
Creates string generator define by size and range of characters.
Definition tgen.h:3062
static instance abacaba(int n)
Returns the prefix of the infinite word "abacabad...".
Definition tgen.h:3229
str & equal_range(int left, int right)
Restricts generator s.t. all values at index range are the same.
Definition tgen.h:3092
str & fix(int idx, char character)
Restricts generator s.t. character at index is fixed.
Definition tgen.h:3078
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.
Definition tgen.h:3261
str & palindrome()
Restricts generator s.t. string is a palindrome.
Definition tgen.h:3109
str(int size, std::set< char > chars)
Creates string generator define by character set.
Definition tgen.h:3067
Unique generator for containers.
Definition tgen.h:792
auto gen_list(int size)
Generates a list of several unique elements.
Definition tgen.h:813
T gen()
Generates a unique random element from the container.
Definition tgen.h:809
size_t size() const
Returns the number of elements left to generate.
Definition tgen.h:805
unique_container(const C &container)
Creates unique generator for elements of the given container.
Definition tgen.h:798
auto gen_all()
Generates all unique elements left to generate.
Definition tgen.h:822
Unique generator for integral ranges.
Definition tgen.h:743
auto gen_list(int size)
Generates a list of several unique values.
Definition tgen.h:774
T gen()
Generates a unique random value in the defined range.
Definition tgen.h:756
auto gen_all()
Generates all unique values left to generate.
Definition tgen.h:783
unique_range(T l, T r)
Creates unique generator for values in given range.
Definition tgen.h:749
T size() const
Returns the number of values left to generate.
Definition tgen.h:752
Unique generator for discrete uniform functions.
Definition tgen.h:229
bool empty()
Checks if there is nothing left to generate.
Definition tgen.h:293
auto gen_list(int size)
Generates a list of several unique values.
Definition tgen.h:282
auto gen()
Generates a unique value.
Definition tgen.h:270
unique(Func func, Args... args)
Generates a unique generator of a discrete uniform function.
Definition tgen.h:235
auto gen_all()
Generates all unique values left to generate.
Definition tgen.h:296