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 <functional>
27#include <iomanip>
28#include <iostream>
29#include <map>
30#include <optional>
31#include <queue>
32#include <random>
33#include <set>
34#include <sstream>
35#include <stdexcept>
36#include <string>
37#include <sys/types.h>
38#include <type_traits>
39#include <utility>
40#include <vector>
41
42namespace tgen {
43
44/**************************
45 * *
46 * GENERAL OPERATIONS *
47 * *
48 **************************/
49
50namespace detail {
51
52// Type aliases.
53using u128 = unsigned __int128;
54using i128 = __int128;
55
56/*
57 * Error handling.
58 */
59
60inline void throw_assertion_error(const std::string &condition,
61 const std::string &msg) {
62 throw std::runtime_error("tgen: " + msg + " (assertion `" + condition +
63 "` failed)");
64}
65inline void throw_assertion_error(const std::string &condition) {
66 throw std::runtime_error("tgen: assertion `" + condition + "` failed");
67}
68inline std::runtime_error error(const std::string &msg) {
69 return std::runtime_error("tgen: " + msg);
70}
71inline std::runtime_error contradiction_error(const std::string &type,
72 const std::string &msg = "") {
73 // Tried to generate a contradicting type.
74 std::string error_msg =
75 type + ": invalid " + type + " (contradicting restrictions)";
76 if (!msg.empty())
77 error_msg += ": " + msg;
78 return error(error_msg);
79}
80inline std::runtime_error
81complex_restrictions_error(const std::string &type,
82 const std::string &msg = "") {
83 // Tried to generate a type with too many distinct restrictions.
84 std::string error_msg =
85 type + ": cannot represent " + type + " (complex restrictions)";
86 if (!msg.empty())
87 error_msg += ": " + msg;
88 return error(error_msg);
89}
90inline void tgen_ensure_against_bug(bool cond, const std::string &msg = "") {
91 if (!cond) {
92 std::string error_msg;
93 if (!msg.empty())
94 error_msg = "tgen: " + msg + "\n";
95 error_msg += "tgen: THERE IS A BUG IN TGEN; PLEASE CONTACT MAINTAINERS";
96 throw std::runtime_error(error_msg);
97 }
98}
99
100// Ensures condition is true, with nice debug.
101#define tgen_ensure(cond, ...)
102 if (!(cond))
103 tgen::detail::throw_assertion_error(#cond, ##__VA_ARGS__);
104
105// Registering checks.
106inline bool registered = false;
107inline void ensure_registered() {
108 tgen_ensure(registered,
109 "tgen was not registered! You should call "
110 "tgen::register_gen(argc, argv) before running tgen functions");
111}
112
113// Template magic to detect types in compile time.
114
115// Detects containers != std::string.
116template <typename T, typename = void> struct is_container : std::false_type {};
117template <typename T>
118struct is_container<T,
119 std::void_t<typename std::remove_reference_t<T>::value_type,
120 decltype(std::begin(std::declval<T>())),
121 decltype(std::end(std::declval<T>()))>>
122 : std::true_type {};
123// Exclude all basic_string variants
124template <typename Char, typename Traits, typename Alloc>
125struct is_container<std::basic_string<Char, Traits, Alloc>> : std::false_type {
126};
127template <typename Char, typename Traits, typename Alloc>
128struct is_container<const std::basic_string<Char, Traits, Alloc>>
129 : std::false_type {};
130template <typename Char, typename Traits, typename Alloc>
131struct is_container<std::basic_string<Char, Traits, Alloc> &>
132 : std::false_type {};
133template <typename Char, typename Traits, typename Alloc>
134struct is_container<const std::basic_string<Char, Traits, Alloc> &>
135 : std::false_type {};
136
137// Detects std::pair.
138template <typename T> struct is_pair : std::false_type {};
139template <typename A, typename B>
140struct is_pair<std::pair<A, B>> : std::true_type {};
141// Detects std::tuple.
142template <typename T> struct is_tuple : std::false_type {};
143template <typename... Ts>
144struct is_tuple<std::tuple<Ts...>> : std::true_type {};
145// Detects scalar (printed atomically).
146template <typename T>
149 !is_pair<T>::value> {};
150// Detects complex container.
151template <typename T>
157// Detects complex std::pair.
158template <typename T> struct is_pair_multiline : std::false_type {};
159template <typename A, typename B>
160struct is_pair_multiline<std::pair<A, B>>
162// Detects complex std::tuple.
163template <typename Tuple> struct is_tuple_multiline : std::false_type {};
164template <typename... Ts>
165struct is_tuple_multiline<std::tuple<Ts...>>
166 : std::bool_constant<(!is_scalar<Ts>::value or ...)> {};
167
168/*
169 * Properties of custom types.
170 */
171
172// If type is sequential (list-like).
173using is_sequential_tag = void;
174
175// If it makes sense to have a subset of the type.
176using has_subset_defined_tag = void;
177
178/*
179 * Unique rng to use.
180 */
181
182// The single rng to be used by the library.
183inline std::mt19937 rng;
184
185// Used to return false in compile time only if evaluated.
186template <typename> inline constexpr bool dependent_false_v = false;
187
188/*
189 * C++ version types.
190 */
191
192// Global C++ version value (0 means unknown).
193struct cpp_value {
194 int version_;
195
196 cpp_value(std::optional<int> version = std::nullopt)
197 : version_(version ? *version : 0) {
198 if (version) {
199 tgen_ensure(*version == 17 or *version == 20 or *version == 23,
200 "unsupported C++ version (use 17, 20, 23)");
201 }
202 }
203};
204inline cpp_value cpp;
205
206/*
207 * Compiler types.
208 */
209
210// Kinds of compilers.
211enum class compiler_kind { gcc, clang, unknown };
212
213// Global compiler value.
214struct compiler_value {
215 compiler_kind kind_;
216 int major_;
217 int minor_;
218
219 compiler_value(compiler_kind kind = compiler_kind::unknown, int major = 0,
220 int minor = 0)
221 : kind_(kind), major_(major), minor_(minor) {}
222};
223inline compiler_value compiler;
224
225} // namespace detail
226
227/*
228 * Base classes.
229 */
230
231// Needed for return type of some functions.
232template <typename T> struct list;
233
234// Generates distinct values of a function.
235template <typename Func, typename... Args> struct distinct {
236 Func func_;
237 std::tuple<Args...> args_;
238 using T = std::invoke_result_t<Func &, Args &...>;
239 std::set<T> seen_;
240
241 distinct(Func func, Args... args)
242 : func_(std::move(func)), args_(std::move(args)...) {}
243
244 // Generates distinct value and inserts it if `insert` is true.
245 // Returns the value if found, otherwise returns std::nullopt.
246 auto generate_distinct(bool insert) {
247 for (int i = 0; i < 84 * std::max<int>(1, seen_.size()); ++i) {
248 T val = std::apply(func_, args_);
249 if (insert ? seen_.insert(val).second : seen_.count(val) == 0)
250 return std::optional<T>(val);
251 }
252
253 // Not found.
254 return std::optional<T>();
255 }
256
257 // Generates a distinct value (i.e., one not returned before).
258 //
259 // Assume gen() produces a uniformly random value in O(T) time.
260 // Since duplicates are rejected, the expected number of trials over
261 // k successful generations is:
262 //
263 // sum_{i=1}^k k / i = O(k log k)
264 //
265 // (coupon collector argument).
266 //
267 // Each trial additionally performs O(log k) work to check/store
268 // previously generated values, yielding a total time of
269 // O((T + log k) * k log k).
270 //
271 // Thus, the amortized expected time per call is
272 // O(T * log k + log^2 k).
273 //
274 // With extremely small probability (< 1e-18), the algorithm may
275 // incorrectly report that no more distinct values exist.
276 auto gen() {
277 auto val = generate_distinct(true);
278 if (val)
279 return *val;
280
281 throw detail::error("no more distinct values");
282 }
283 template <typename U> auto gen(std::initializer_list<U> il) {
284 return gen(std::vector<U>(il));
285 }
286
287 // Generates a list of distinct values.
288 auto gen_list(int size) {
289 std::vector<T> res;
290 for (int i = 0; i < size; ++i)
291 res.push_back(gen());
292
293 return typename list<T>::value(res);
294 }
295
296 // Checks if there are no more distinct values.
297 // With extremely small probability (< 1e-18), the algorithm may
298 // incorrectly report that there are no more distinct values.
299 bool empty() { return generate_distinct(false) == std::nullopt; }
300
301 // Generates all distinct values.
302 auto gen_all() {
303 std::vector<T> res;
304 while (true) {
305 auto val = generate_distinct(true);
306 if (val)
307 res.push_back(*val);
308 else
309 break;
310 }
311 return typename list<T>::value(res);
312 }
313
314 // Nice error for `out << distinct`.
315 friend std::ostream &operator<<(std::ostream &out, const distinct &) {
316 static_assert(detail::dependent_false_v<distinct>,
317 "cannot print a distinct generator. Maybe you forgot to "
318 "call `gen()`?");
319 return out;
320 }
321};
322template <typename Func, typename... Args>
323distinct(Func, Args...) -> distinct<Func, Args...>;
324
325// Base struct for generators.
326template <typename Gen> struct gen_base {
327 const Gen &self() const { return *static_cast<const Gen *>(this); }
328
329 template <typename... Args> auto gen_list(int size, Args &&...args) const {
330 std::vector<typename Gen::value> res;
331
332 for (int i = 0; i < size; ++i)
333 res.push_back(static_cast<const Gen *>(this)->gen(
334 std::forward<Args>(args)...));
335
336 return typename list<typename Gen::value>::value(res);
337 }
338
339 // Calls the generator until predicate is true.
340 template <typename Pred, typename... Args>
341 auto gen_until(Pred predicate, int max_tries, Args &&...args) const {
342 for (int i = 0; i < max_tries; ++i) {
343 typename Gen::value inst = static_cast<const Gen *>(this)->gen(
344 std::forward<Args>(args)...);
345
346 if (predicate(inst))
347 return inst;
348 }
349
350 throw detail::error("could not generate value matching predicate");
351 }
352 template <typename Pred, typename T, typename... Args>
353 auto gen_until(Pred predicate, int max_tries, std::initializer_list<T> il,
354 Args &&...args) const {
355 return gen_until(predicate, max_tries, std::vector<T>(il),
356 std::forward<Args>(args)...);
357 }
358
359 // Distinct for generator.
360 template <typename... Args> auto distinct(Args &&...args) const {
361 return tgen::distinct(
362 [self = self()](auto &&...inner_args) mutable -> decltype(auto) {
363 return self.gen(
364 std::forward<decltype(inner_args)>(inner_args)...);
365 },
366 std::forward<Args>(args)...);
367 }
368 template <typename T, typename... Args>
369 auto distinct(std::initializer_list<T> il, Args &&...args) const {
370 return distinct(std::vector<T>(il), std::forward<Args>(args)...);
371 }
372
373 // Nice error for `out << generator`.
374 friend std::ostream &operator<<(std::ostream &out, const gen_base &) {
375 static_assert(
376 detail::dependent_false_v<gen_base>,
377 "cannot print a generator. Maybe you forgot to call `gen()`?");
378 return out;
379 }
380};
381
382// Base class for generator values.
383template <typename Inst> struct gen_value_base {
384 const Inst &self() const { return *static_cast<const Inst *>(this); }
385
386 bool operator<(const Inst &rhs) const {
387 return self().to_std() < rhs.to_std();
388 }
389};
390
391/*
392 * Type compile-time detection.
393 */
394
395// Detects associative containers.
396template <typename T, typename = void>
397struct is_associative_container : std::false_type {};
398template <typename T>
399struct is_associative_container<
400 T, std::void_t<typename T::key_type, typename T::key_compare>>
401 : std::true_type {};
402
403// Detects generator values.
404template <typename T>
407
408// Detects sequential generator values.
409template <typename T, typename = void>
410struct is_sequential : std::false_type {};
411template <typename T>
412struct is_sequential<
413 T, std::void_t<typename std::decay_t<T>::tgen_is_sequential_tag>>
414 : std::true_type {};
415
416// Detects generator values with defined subset.
417template <typename T, typename = void>
418struct has_subset_defined : std::false_type {};
419template <typename T>
420struct has_subset_defined<
421 T, std::void_t<typename std::decay_t<T>::tgen_has_subset_defined_tag>>
422 : std::true_type {};
423
424/*
425 * Easier printing.
426 */
427
428// Struct to print standard types to std::ostream;
429struct print {
430 std::string s_;
431
432 template <typename T> print(const T &val, char sep = ' ') {
433 std::ostringstream oss;
434 write(oss, val, sep);
435 s_ = oss.str();
436 }
437 template <typename T>
438 print(const std::initializer_list<T> &il, char sep = ' ') {
439 std::ostringstream oss;
440 write(oss, std::vector<T>(il), sep);
441 s_ = oss.str();
442 }
443 template <typename T>
444 print(const std::initializer_list<std::initializer_list<T>> &il,
445 char sep = ' ') {
446 std::ostringstream oss;
447 std::vector<std::vector<T>> mat;
448 for (const auto &i : il)
449 mat.push_back(i);
450 write(oss, mat, sep);
451 s_ = oss.str();
452 }
453
454 template <typename T>
455 void write(std::ostream &os, const T &val, char sep = ' ') {
456 if constexpr (detail::is_pair<T>::value) {
457 if constexpr (detail::is_pair_multiline<T>::value) {
458 write(os, val.first, sep);
459 os << '\n';
460 write(os, val.second, sep);
461 } else {
462 write(os, val.first);
463 os << sep;
464 write(os, val.second);
465 }
466 } else if constexpr (detail::is_tuple<T>::value)
467 write_tuple(os, val, sep);
468 else if constexpr (detail::is_container<T>::value)
469 write_container(os, val, sep);
470 else if constexpr (std::is_same_v<T, detail::i128> or
471 std::is_same_v<T, detail::u128>)
472 write_128_number(os, val);
473 else
474 os << val;
475 }
476
477 // Writes 128 bit number.
478 template <typename T> void write_128_number(std::ostream &os, T num) {
479 static const long long BASE = 1e18;
480
481 if (num < 0) {
482 os << '-';
483 num = -num;
484 }
485
486 if (num >= BASE) {
487 write_128_number(os, num / BASE);
488 os << std::setw(18) << std::setfill('0')
489 << static_cast<long long>(num % BASE);
490 } else
491 os << static_cast<long long>(num);
492 }
493 // Writes container, checking separator.
494 template <typename C>
495 void write_container(std::ostream &os, const C &container, char sep = ' ') {
496 bool first = true;
497
498 for (const auto &e : container) {
499 if (!first)
500 os << (detail::is_container_multiline<C>::value ? '\n' : sep);
501 first = false;
502 write(os, e, detail::is_container_multiline<C>::value ? sep : ' ');
503 }
504 }
505
506 // Writes tuple, checking separator.
507 template <typename Tuple, size_t... I>
508 void write_tuple_impl(std::ostream &os, const Tuple &tp, char sep,
509 std::index_sequence<I...>) {
510 bool first = true;
511 ((os << (first ? (first = false, "")
512 : (detail::is_tuple_multiline<Tuple>::value
513 ? "\n"
514 : std::string(1, sep))),
515 write(os, std::get<I>(tp),
516 detail::is_tuple_multiline<Tuple>::value ? sep : ' ')),
517 ...);
518 }
519 template <typename T>
520 void write_tuple(std::ostream &os, const T &tp, char sep = ' ') {
521 write_tuple_impl(os, tp, sep,
522 std::make_index_sequence<std::tuple_size<T>::value>{});
523 }
524
525 friend std::ostream &operator<<(std::ostream &out, const print &pr) {
526 return out << pr.s_;
527 }
528};
529
530// Prints in a new line.
531struct println : print {
532 template <typename T>
533 println(const T &val, char sep = ' ') : print(val, sep) {}
534 template <typename T>
535 println(const std::initializer_list<T> &il, char sep = ' ')
536 : print(il, sep) {}
537 template <typename T>
538 println(const std::initializer_list<std::initializer_list<T>> &il,
539 char sep = ' ')
540 : print(il, sep) {}
541
542 friend std::ostream &operator<<(std::ostream &out, const println &pr) {
543 return out << pr.s_ << '\n';
544 }
545};
546
547/*
548 * Global random operations.
549 */
550
551// Returns a uniformly random number in [0, right)
552// O(1).
553template <typename T> T next(T right) {
554 detail::ensure_registered();
555 if constexpr (std::is_integral_v<T>) {
556 tgen_ensure(right >= 1, "value for `next` must be valid");
557 return std::uniform_int_distribution<T>(0, right - 1)(detail::rng);
558 } else if constexpr (std::is_floating_point_v<T>) {
559 tgen_ensure(right >= 0, "value for `next` must be valid");
560 return std::uniform_real_distribution<T>(0, right)(detail::rng);
561 } else
562 throw detail::error("invalid type for next (" +
563 std::string(typeid(T).name()) + ")");
564}
565
566// Returns a uniformly random number in [l, r].
567// O(1).
568template <typename T> T next(T left, T right) {
569 detail::ensure_registered();
570 tgen_ensure(left <= right, "range for `next` must be valid");
571 if constexpr (std::is_integral_v<T>)
572 return std::uniform_int_distribution<T>(left, right)(detail::rng);
573 else if constexpr (std::is_floating_point_v<T>)
574 return std::uniform_real_distribution<T>(left, right)(detail::rng);
575 else
576 throw detail::error("invalid type for next (" +
577 std::string(typeid(T).name()) + ")");
578}
579
580namespace detail {
581
582// Uniformly random 128 bit number in [0, total).
583// O(1) expected.
584inline u128 next128(u128 total) {
585 tgen_ensure(total > 0, "next128: total must be positive");
586
587 // Largest multiple of total less than 2^128.
588 u128 limit = (u128(-1) / total) * total;
589
590 while (true) {
591 // Generate uniform 128-bit random number.
592 u128 r = ((u128)next<uint64_t>(0, std::numeric_limits<uint64_t>::max())
593 << 64) |
594 next<uint64_t>(0, std::numeric_limits<uint64_t>::max());
595
596 if (r < limit)
597 return r % total;
598 }
599}
600
601} // namespace detail
602
603// Returns i with probability proportional to distribution[i].
604template <typename T>
605size_t next_by_distribution(const std::vector<T> &distribution) {
606 tgen_ensure(distribution.size() > 0, "distribution must be non-empty");
607
608 T r = next<T>(
609 std::accumulate(distribution.begin(), distribution.end(), T(0)));
610 for (size_t i = 0; i < distribution.size(); ++i) {
611 if (r < distribution[i])
612 return i;
613 r -= distribution[i];
614 }
615 return distribution.size() - 1;
616}
617template <typename T>
618size_t next_by_distribution(const std::initializer_list<T> &distribution) {
619 return next_by_distribution(std::vector<T>(distribution));
620}
621
622// Shuffles [first, last) inplace uniformly, for RandomAccessIterator.
623// O(|container|).
624template <typename It> void shuffle(It first, It last) {
625 if (first == last)
626 return;
627
628 for (It i = first + 1; i != last; ++i)
629 std::iter_swap(i, first + next(0, static_cast<int>(i - first)));
630}
631
632// Shuffles sequential generator value uniformly.
633// O(|inst|).
634template <typename Inst, std::enable_if_t<is_sequential<Inst>::value, int> = 0>
635void shuffle(Inst &inst) {
636 for (int i = 0; i < inst.size(); ++i)
637 std::swap(inst[i], inst[next(0, inst.size() - 1)]);
638}
639
640// Shuffles container uniformly.
641// O(|container|).
642template <typename C, std::enable_if_t<!is_generator_value<C>::value, int> = 0>
643[[nodiscard]] auto shuffled(const C &container) {
644 if constexpr (is_associative_container<C>::value) {
645 std::vector<typename C::value_type> vec(container.begin(),
646 container.end());
647 shuffle(vec.begin(), vec.end());
648 return vec;
649 } else {
650 auto new_container = container;
651 shuffle(new_container.begin(), new_container.end());
652 return new_container;
653 }
654}
655template <typename T>
656[[nodiscard]] std::vector<T> shuffled(const std::initializer_list<T> &il) {
657 return shuffled(std::vector<T>(il));
658}
659
660// Shuffles sequential generator value uniformly.
661// O(n).
662template <typename Inst, std::enable_if_t<is_sequential<Inst>::value, int> = 0>
663[[nodiscard]] Inst shuffled(const Inst &inst) {
664 Inst new_inst = inst;
665 shuffle(new_inst);
666 return new_inst;
667}
668
669// Returns a random element from [first, last) uniformly.
670// O(1) for random_access_iterator, O(|last - first|) otherwise.
671template <typename It> typename It::value_type pick(It first, It last) {
672 int size = std::distance(first, last);
673 It it = first;
674 std::advance(it, next(0, size - 1));
675 return *it;
676}
677
678// Returns a random element from container uniformly.
679// O(1) for random_access_iterator, O(|container|) otherwise.
680template <typename C, std::enable_if_t<!is_generator_value<C>::value, int> = 0>
681typename C::value_type pick(const C &container) {
682 return pick(container.begin(), container.end());
683}
684template <typename T> T pick(const std::initializer_list<T> &il) {
685 return pick(std::vector<T>(il));
686}
687
688// Returns a random element from sequential generator value uniformly.
689// O(1).
690template <typename Inst, std::enable_if_t<is_sequential<Inst>::value, int> = 0>
691typename Inst::value_type pick(const Inst &inst) {
692 return inst[next<int>(0, inst.size() - 1)];
693}
694
695// Returns container[i] with probability proportional to distribution[i].
696// O(1) for random_access_iterator, O(|container|) otherwise.
697template <typename C, typename T,
698 std::enable_if_t<!is_generator_value<C>::value, int> = 0>
699typename C::value_type pick_by_distribution(const C &container,
700 std::vector<T> distribution) {
701 tgen_ensure(container.size() == distribution.size(),
702 "container and distribution must have the same size");
703 auto it = container.begin();
704 std::advance(it, next_by_distribution(distribution));
705 return *it;
706}
707template <typename C, typename T,
708 std::enable_if_t<!is_generator_value<C>::value, int> = 0>
709typename C::value_type
710pick_by_distribution(const C &container,
711 const std::initializer_list<T> &distribution) {
712 return pick_by_distribution(container, std::vector<T>(distribution));
713}
714template <typename T, typename U>
715T pick_by_distribution(const std::initializer_list<T> &il,
716 const std::vector<U> &distribution) {
717 return pick_by_distribution(std::vector<T>(il), distribution);
718}
719template <typename T, typename U>
720T pick_by_distribution(const std::initializer_list<T> &il,
721 const std::initializer_list<U> &distribution) {
722 return pick_by_distribution(std::vector<T>(il),
723 std::vector<U>(distribution));
724}
725
726// Returns inst[i] with probability proportional to distribution[i].
727// O(1).
728template <typename Inst, typename T,
729 std::enable_if_t<is_sequential<Inst>::value, int> = 0>
730typename Inst::value_type
731pick_by_distribution(const Inst &inst, const std::vector<T> &distribution) {
732 tgen_ensure(static_cast<size_t>(inst.size()) == distribution.size(),
733 "inst and distribution must have the same size");
734 return inst[next_by_distribution(distribution)];
735}
736template <typename Inst, typename T,
737 std::enable_if_t<is_sequential<Inst>::value, int> = 0>
738typename Inst::value_type
739pick_by_distribution(const Inst &inst,
740 const std::initializer_list<T> &distribution) {
741 return pick_by_distribution(inst, std::vector<T>(distribution));
742}
743
744// Chooses k values uniformly from container, as in a subsequence of size k.
745// Returns a copy. O(|container|).
746template <typename C, std::enable_if_t<!is_generator_value<C>::value, int> = 0>
747C choose(const C &container, int k) {
748 tgen_ensure(0 < k and k <= static_cast<int>(container.size()),
749 "number of elements to choose must be valid");
750 std::vector<typename C::value_type> new_vec;
751 C new_container;
752 int need = k, left = container.size();
753 for (auto cur_it = container.begin(); cur_it != container.end(); ++cur_it) {
754 if (next(1, left--) <= need) {
755 new_container.insert(new_container.end(), *cur_it);
756 need--;
757 }
758 }
759 return new_container;
760}
761template <typename T>
762std::vector<T> choose(const std::initializer_list<T> &il, int k) {
763 return choose(std::vector<T>(il), k);
764}
765
766// Chooses k values uniformly from sequential generator value, as in a
767// subsequence of size k.
768// O(n).
769template <typename Inst, std::enable_if_t<is_sequential<Inst>::value and
770 has_subset_defined<Inst>::value,
771 int> = 0>
772Inst choose(const Inst &inst, int k) {
773 tgen_ensure(0 < k and k <= static_cast<int>(inst.size()),
774 "number of elements to choose must be valid");
775 std::vector<typename Inst::value_type> new_vec;
776 int need = k;
777 for (int i = 0; need > 0; ++i) {
778 int left = inst.size() - i;
779 if (next(1, left) <= need) {
780 new_vec.push_back(inst[i]);
781 need--;
782 }
783 }
784 return Inst(new_vec);
785}
786
787// Number distinct generator for integral types.
788template <typename T> struct distinct_range {
789 T l_, r_;
790 T num_available_;
791 std::map<T, T> virtual_list_;
792
793 // Generator of distinct values in [l_, r_].
794 distinct_range(T l, T r) : l_(l), r_(r), num_available_(r - l + 1) {}
795
796 // Returns the number of distinct values left to generate.
797 T size() const { return num_available_; }
798
799 // Generates a random value in [l_, r_] that has not been generated yet.
800 // O(log n).
801 T gen() {
802 // One iteration of Fisher–Yates.
803 tgen_ensure(size() > 0, "distinct_range: no more values to generate");
804
805 T i = next<T>(0, size() - 1);
806 T j = size() - 1;
807
808 T vi = virtual_list_.count(i) ? virtual_list_[i] : i;
809 T vj = virtual_list_.count(j) ? virtual_list_[j] : j;
810 virtual_list_[i] = vj;
811
812 --num_available_;
813
814 return vi + l_;
815 }
816
817 // Generates a list of distict values.
818 // O(size * log(n)).
819 auto gen_list(int size) {
820 std::vector<T> res;
821 for (int i = 0; i < size; ++i)
822 res.push_back(gen());
823 return typename list<T>::value(res);
824 }
825
826 // Generates all distict values.
827 // O(n log(n))
828 auto gen_all() {
829 std::vector<T> res;
830 while (size() > 0)
831 res.push_back(gen());
832 return typename list<T>::value(res);
833 }
834};
835
836// Distinct generator for containers.
837template <typename T> struct distinct_container {
838 std::vector<T> list_;
839 distinct_range<size_t> idx_;
840
841 // Creates a distinct container generator for the given container.
842 template <typename C>
843 distinct_container(const C &container)
845 idx_(0, static_cast<int>(container.size()) - 1) {}
846 distinct_container(const std::initializer_list<T> &il)
847 : distinct_container(std::vector<T>(il)) {}
848
849 // Returns the number of distinct elements left to generate.
850 size_t size() const { return idx_.size(); }
851
852 // Generates a random element from container uniformly.
853 // O(log n).
854 T gen() { return list_[idx_.gen()]; }
855
856 // Generates a list of distinct values.
857 // O(size * log(n)).
858 auto gen_list(int size) {
859 std::vector<T> res;
860 for (int i = 0; i < size; ++i)
861 res.push_back(gen());
862 return typename list<T>::value(res);
863 }
864
865 // Generates all distinct values.
866 // O(n log(n))
867 auto gen_all() {
868 std::vector<T> res;
869 while (size() > 0)
870 res.push_back(gen());
871 return typename list<T>::value(res);
872 }
873};
874template <typename C>
875distinct_container(const C &) -> distinct_container<typename C::value_type>;
876
877/************
878 * *
879 * OPTS *
880 * *
881 ************/
882
883/*
884 * Opts - options given to the generator.
885 *
886 * Incompatible with testlib.
887 *
888 * Opts are a list of either positional or named options.
889 *
890 * Named options is given in one of the following formats:
891 * 1) -keyname=value or --keyname=value (ex. -n=10 , --test-count=20)
892 * 2) -keyname value or --keyname value (ex. -n 10 , --test-count 20)
893 *
894 * Positional options are number from 0 sequentially.
895 * For example, for "10 -n=20 str" positional option 1 is the string "str".
896 */
897
898/*
899 * C++ version selection.
900 */
901
902// Sets C++ version.
903inline void set_cpp_version(int version) {
904 detail::cpp = detail::cpp_value(version);
905}
906
907/*
908 * Compiler selection.
909 */
910
911// GCC compiler type.
912inline detail::compiler_value gcc(int major = 0, int minor = 0) {
913 return {detail::compiler_kind::gcc, major, minor};
914}
915
916// Clang compiler type.
917inline detail::compiler_value clang(int major = 0, int minor = 0) {
918 return {detail::compiler_kind::clang, major, minor};
919}
920
921// Sets compiler.
922inline void set_compiler(detail::compiler_value compiler) {
923 detail::compiler.kind_ = compiler.kind_;
924 detail::compiler.major_ = compiler.major_;
925 detail::compiler.minor_ = compiler.minor_;
926}
927
928namespace detail {
929
930// Processes special opt flags.
931// Returns true if the key is a special opt flag.
932inline bool process_special_opt_flags(std::string &key) {
933 // Checks for gen::CPP=17|20|23
934 if (key.find("tgen::CPP:") == 0) {
935 int prefix_len = std::string("tgen::CPP:").size();
936 tgen_ensure(static_cast<int>(key.size()) == prefix_len + 2 and
937 std::isdigit(key[prefix_len]) and
938 std::isdigit(key[prefix_len + 1]),
939 "invalid CPP format");
940 int version = std::stoi(key.substr(prefix_len, 2));
941 set_cpp_version(version);
942 return true;
943 }
944
945 // Checks for tgen::(GCC|CLANG) or
946 // tgen::(GCC|CLANG):(version|version.minor).
947 compiler_kind kind;
948 size_t prefix_len = 0;
949
950 if (key.find("tgen::GCC") == 0) {
951 kind = compiler_kind::gcc;
952 prefix_len = std::string("tgen::GCC").size();
953 } else if (key.find("tgen::CLANG") == 0) {
954 kind = compiler_kind::clang;
955 prefix_len = std::string("tgen::CLANG").size();
956 } else {
957 return false;
958 }
959
960 if (key.size() == prefix_len) {
961 set_compiler(compiler_value(kind, 0, 0));
962 return true;
963 }
964
965 tgen_ensure(key[prefix_len] == ':', "invalid compiler format");
966 ++prefix_len; // for ':'.
967
968 std::string inside = key.substr(prefix_len, key.size() - prefix_len);
969 int major = 0, minor = 0;
970
971 size_t dot = inside.find('.');
972 if (dot == std::string::npos) {
973 tgen_ensure(!inside.empty() and
974 std::all_of(inside.begin(), inside.end(), ::isdigit),
975 "invalid compiler version");
976 major = std::stoi(inside);
977 } else {
978 std::string maj = inside.substr(0, dot);
979 std::string min = inside.substr(dot + 1);
980
981 tgen_ensure(!maj.empty() and
982 std::all_of(maj.begin(), maj.end(), ::isdigit) and
983 maj.size() <= 3,
984 "invalid compiler major version");
985 tgen_ensure(!min.empty() and
986 std::all_of(min.begin(), min.end(), ::isdigit) and
987 min.size() <= 3,
988 "invalid compiler minor version");
989
990 major = std::stoi(maj);
991 minor = std::stoi(min);
992 }
993
994 set_compiler(compiler_value(kind, major, minor));
995
996 return true;
997}
998
999inline std::vector<std::string>
1000 pos_opts; // Dictionary containing the positional parsed opts.
1001inline std::map<std::string, std::string>
1002 named_opts; // Global dictionary the named parsed opts.
1003
1004template <typename T> T get_opt(const std::string &value) {
1005 try {
1006 if constexpr (std::is_same_v<T, bool>) {
1007 if (value == "true" or value == "1")
1008 return true;
1009 if (value == "false" or value == "0")
1010 return false;
1011 } else if constexpr (std::is_integral_v<T>) {
1012 if constexpr (std::is_unsigned_v<T>)
1013 return static_cast<T>(std::stoull(value));
1014 else
1015 return static_cast<T>(std::stoll(value));
1016 } else if constexpr (std::is_floating_point_v<T>)
1017 return static_cast<T>(std::stold(value));
1018 else
1019 return value; // default: std::string
1020 } catch (...) {
1021 }
1022
1023 throw error("invalid value `" + value + "` for type " + typeid(T).name());
1024}
1025
1026inline void parse_opts(int argc, char **argv) {
1027 // Parses the opts into `pos_opts` vector and `named_opts`
1028 // map. Starting from 1 to ignore the name of the executable.
1029 for (int i = 1; i < argc; ++i) {
1030 std::string key(argv[i]);
1031
1032 if (process_special_opt_flags(key))
1033 continue;
1034
1035 if (key[0] == '-') {
1036 tgen_ensure(key.size() > 1,
1037 "invalid opt (" + std::string(argv[i]) + ")");
1038 if ('0' <= key[1] and key[1] <= '9') {
1039 // This case is a positional negative number argument
1040 pos_opts.push_back(key);
1041 continue;
1042 }
1043
1044 // pops first char '-'
1045 key = key.substr(1);
1046 } else {
1047 // This case is a positional argument that does not start with '-'
1048 pos_opts.push_back(key);
1049 continue;
1050 }
1051
1052 // Pops a possible second char '-'.
1053 if (key[0] == '-') {
1054 tgen_ensure(key.size() > 1,
1055 "invalid opt (" + std::string(argv[i]) + ")");
1056
1057 // pops first char '-'
1058 key = key.substr(1);
1059 }
1060
1061 // Assumes that, if it starts with '-' and second char is not a digit,
1062 // then it is a <key, value> pair.
1063 // 1 or 2 chars '-' have already been poped.
1064
1065 std::size_t eq = key.find('=');
1066 if (eq != std::string::npos) {
1067 // This is the '--key=value' case.
1068 std::string value = key.substr(eq + 1);
1069 key = key.substr(0, eq);
1070 tgen_ensure(!key.empty() and !value.empty(),
1071 "expected non-empty key/value in opt (" +
1072 std::string(argv[1]));
1073 tgen_ensure(named_opts.count(key) == 0,
1074 "cannot have repeated keys");
1075 named_opts[key] = value;
1076 } else {
1077 // This is the '--key value' case.
1078 tgen_ensure(named_opts.count(key) == 0,
1079 "cannot have repeated keys");
1080 tgen_ensure(argv[i + 1], "value cannot be empty");
1081 named_opts[key] = std::string(argv[i + 1]);
1082 ++i;
1083 }
1084 }
1085}
1086
1087inline void set_seed(int argc, char **argv) {
1088 std::vector<uint32_t> seed;
1089
1090 // Starting from 1 to ignore the name of the executable.
1091 for (int i = 1; i < argc; ++i) {
1092 // We append the number of chars, and then the list of chars.
1093 int size_pos = seed.size();
1094 seed.push_back(0);
1095 for (char *s = argv[i]; *s != '\0'; ++s) {
1096 ++seed[size_pos];
1097 seed.push_back(*s);
1098 }
1099 }
1100 std::seed_seq seq(seed.begin(), seed.end());
1101 rng.seed(seq);
1102}
1103
1104} // namespace detail
1105
1106// Returns true if there is an opt at a given index.
1107inline bool has_opt(std::size_t index) {
1108 detail::ensure_registered();
1109 return 0 <= index and index < detail::pos_opts.size();
1110}
1111
1112// Returns true if there is an opt with a given key.
1113inline bool has_opt(const std::string &key) {
1114 detail::ensure_registered();
1115 return detail::named_opts.count(key) != 0;
1116}
1117template <typename K>
1118std::enable_if_t<std::is_same_v<K, char>, bool> has_opt(K key) {
1119 return has_opt(std::string(1, key));
1120}
1121
1122// Returns the parsed opt by a given index. If no opts with the given index are
1123// found, returns the given default_value.
1124template <typename T>
1125T opt(size_t index, std::optional<T> default_value = std::nullopt) {
1126 detail::ensure_registered();
1127 if (!has_opt(index)) {
1128 if (default_value)
1129 return *default_value;
1130 throw detail::error("cannot find key with index " +
1131 std::to_string(index));
1132 }
1133 return detail::get_opt<T>(detail::pos_opts[index]);
1134}
1135
1136// Returns the parsed opt by a given key. If no opts with the given key are
1137// found, returns the given default_value.
1138template <typename T>
1139T opt(const std::string &key, std::optional<T> default_value = std::nullopt) {
1140 detail::ensure_registered();
1141 if (!has_opt(key)) {
1142 if (default_value)
1143 return *default_value;
1144 throw detail::error("cannot find key with key " + key);
1145 }
1146 return detail::get_opt<T>(detail::named_opts[key]);
1147}
1148template <typename T, typename K>
1149std::enable_if_t<std::is_same_v<K, char>, T>
1150opt(K key, std::optional<T> default_value = std::nullopt) {
1151 return opt<T>(std::string(1, key), default_value);
1152}
1153
1154// Registers generator by initializing rnd and parsing opts.
1155inline void register_gen(int argc, char **argv) {
1156 detail::set_seed(argc, argv);
1157
1158 detail::pos_opts.clear();
1159 detail::named_opts.clear();
1160 detail::parse_opts(argc, argv);
1161
1162 detail::registered = true;
1163}
1164
1165// Registers generator by initializing rnd with a given seed.
1166inline void register_gen(std::optional<long long> seed = std::nullopt) {
1167 if (seed)
1168 detail::rng.seed(*seed);
1169 else
1170 detail::rng.seed();
1171
1172 detail::pos_opts.clear();
1173 detail::named_opts.clear();
1174
1175 detail::registered = true;
1176}
1177
1178/************
1179 * *
1180 * LIST *
1181 * *
1182 ************/
1183
1184/*
1185 * List generator.
1186 *
1187 * List of integral types.
1188 */
1189
1190template <typename T> struct list : gen_base<list<T>> {
1191 int size_; // Size of list.
1192 T value_l_, value_r_; // Range of defined values.
1193 std::set<T> values_; // Set of values. If empty, use range. if not,
1194 // represents the possible values, and the range
1195 // represents the index in this set)
1196 std::map<T, int>
1197 value_idx_in_set_; // Index of every value in the set above.
1198 std::vector<std::pair<T, T>> val_range_; // Range of values of each index.
1199 std::vector<std::vector<int>> neigh_; // Adjacency list of equality.
1200 std::vector<std::set<int>>
1201 diff_restrictions_; // All different restrictions.
1202
1203 // Creates generator for lists of size 'size', with random T in [value_left,
1204 // value_right].
1205 list(int size, T value_left, T value_right)
1206 : size_(size), value_l_(value_left), value_r_(value_right),
1207 neigh_(size) {
1208 tgen_ensure(size_ > 0, "list: size must be positive");
1209 tgen_ensure(value_l_ <= value_r_, "list: value range must be valid");
1210 for (int i = 0; i < size_; ++i)
1211 val_range_.emplace_back(value_l_, value_r_);
1212 }
1213
1214 // Creates list with value set.
1215 list(int size, std::set<T> values)
1216 : size_(size), values_(values), neigh_(size) {
1217 tgen_ensure(size_ > 0, "list: size must be positive");
1218 tgen_ensure(!values.empty(), "list: value set must be non-empty");
1219 value_l_ = 0, value_r_ = values.size() - 1;
1220 for (int i = 0; i < size_; ++i)
1221 val_range_.emplace_back(value_l_, value_r_);
1222 int idx = 0;
1223 for (T val : values_)
1224 value_idx_in_set_[val] = idx++;
1225 }
1226
1227 // Restricts lists for list[idx] = val.
1228 list &fix(int idx, T val) {
1229 tgen_ensure(0 <= idx and idx < size_, "list: index must be valid");
1230 if (values_.size() == 0) {
1231 auto &[left, right] = val_range_[idx];
1232 if (left == right and value_l_ != value_r_) {
1233 tgen_ensure(left == val,
1234 "list: must not set to two different values");
1235 } else {
1236 tgen_ensure(left <= val and val <= right,
1237 "list: value must be in the defined range");
1238 }
1239 left = right = val;
1240 } else {
1241 tgen_ensure(values_.count(val),
1242 "list: value must be in the set of values");
1243 auto &[left, right] = val_range_[idx];
1244 int new_val = value_idx_in_set_[val];
1245 tgen_ensure(left <= new_val and new_val <= right,
1246 "list: must not set to two different values");
1247 left = right = new_val;
1248 }
1249 return *this;
1250 }
1251
1252 // Restricts lists for list[idx_1] = list[idx_2].
1253 list &equal(int idx_1, int idx_2) {
1254 tgen_ensure(0 <= std::min(idx_1, idx_2) and
1255 std::max(idx_1, idx_2) < size_,
1256 "list: indices must be valid");
1257 if (idx_1 == idx_2)
1258 return *this;
1259
1260 neigh_[idx_1].push_back(idx_2);
1261 neigh_[idx_2].push_back(idx_1);
1262 return *this;
1263 }
1264
1265 // Restricts lists for list[S] to be equal, for given subset S of indices.
1266 list &equal(std::set<int> indices) {
1267 if (!indices.empty()) {
1268 std::set<int>::iterator beg = indices.begin();
1269 for (auto it = std::next(beg); it != indices.end(); ++it)
1270 equal(*beg, *it);
1271 }
1272 return *this;
1273 }
1274
1275 // Restricts lists for list[left..right] to have all equal values.
1276 list &equal_range(int left, int right) {
1277 tgen_ensure(0 <= left and left <= right and right < size_,
1278 "list: range indices must be valid");
1279 for (int i = left; i < right; ++i)
1280 equal(i, i + 1);
1281 return *this;
1282 }
1283
1284 // Restricts lists for all equal elements.
1285 list &all_equal() { return equal_range(0, size_ - 1); }
1286
1287 // Restricts lists for list[S] to be different (distinct), for given subset
1288 // S of indices. You can not add two of these restrictions with
1289 // intersection.
1290 list &different(std::set<int> indices) {
1291 if (!indices.empty())
1292 diff_restrictions_.push_back(indices);
1293 return *this;
1294 }
1295
1296 // Restricts lists for list[idx_1] != list[idx_2].
1297 list &different(int idx_1, int idx_2) {
1298 std::set<int> indices = {idx_1, idx_2};
1299 return different(indices);
1300 }
1301
1302 // Restricts lists for list[left..right] to have all different values.
1303 list &different_range(int left, int right) {
1304 tgen_ensure(0 <= left and left <= right and right < size_,
1305 "list: range indices must be valid");
1306 std::vector<int> indices(right - left + 1);
1307 std::iota(indices.begin(), indices.end(), left);
1308 return different(std::set<int>(indices.begin(), indices.end()));
1309 }
1310
1311 // Restricts lists for all different elements.
1313 std::vector<int> indices(size_);
1314 std::iota(indices.begin(), indices.end(), 0);
1315 return different(std::set<int>(indices.begin(), indices.end()));
1316 }
1317
1318 // List value.
1319 // Operations on a value are not random.
1321 using tgen_is_sequential_tag = detail::is_sequential_tag;
1322 using tgen_has_subset_defined_tag = detail::has_subset_defined_tag;
1323
1324 using value_type = T; // Value type, for templates.
1325 using std_type = std::vector<T>; // std type for value.
1326 std::vector<T> vec_; // list.
1327 char sep_; // Separator for printing.
1328
1329 value(const std::vector<T> &vec) : vec_(vec), sep_(' ') {}
1330 value(const std::initializer_list<T> &il) : value(std::vector<T>(il)) {}
1331
1332 // Fetches size.
1333 int size() const { return vec_.size(); }
1334
1335 // Fetches position idx.
1336 T &operator[](int idx) {
1337 tgen_ensure(0 <= idx and idx < size(),
1338 "list: value: index out of bounds");
1339 return vec_[idx];
1340 }
1341 const T &operator[](int idx) const {
1342 tgen_ensure(0 <= idx and idx < size(),
1343 "list: value: index out of bounds");
1344 return vec_[idx];
1345 }
1346
1347 // Sorts values in non-decreasing order.
1348 // O(n log n).
1350 std::sort(vec_.begin(), vec_.end());
1351 return *this;
1352 }
1353
1354 // Reverses list.
1355 // O(n).
1357 std::reverse(vec_.begin(), vec_.end());
1358 return *this;
1359 }
1360
1361 // Sets the separator for the list, for printing.
1362 // O(1).
1363 value &separator(char sep) {
1364 sep_ = sep;
1365 return *this;
1366 }
1367
1368 // Concatenates two values.
1369 // Linear.
1370 value operator+(const value &rhs) {
1371 std::vector<T> new_vec = vec_;
1372 for (int i = 0; i < rhs.size(); ++i)
1373 new_vec.push_back(rhs[i]);
1374 return value(new_vec);
1375 }
1376
1377 // Prints to std::ostream, separated by sep_.
1378 friend std::ostream &operator<<(std::ostream &out, const value &inst) {
1379 for (int i = 0; i < inst.size(); ++i) {
1380 if (i > 0)
1381 out << inst.sep_;
1382 out << inst[i];
1383 }
1384 return out;
1385 }
1386
1387 // Gets a std::vector representing the value.
1388 auto to_std() const {
1389 if constexpr (!is_generator_value<T>::value) {
1390 return vec_;
1391 } else {
1392 std::vector<typename T::std_type> vec;
1393 for (const auto &i : vec_)
1394 vec.push_back(i.to_std());
1395 return vec;
1396 }
1397 }
1398 };
1399
1400 // Generates a uniformly random list of k distinct values in `[value_l,
1401 // value_r]`, such that no value is in `forbidden_values`.
1402 std::vector<T>
1403 generate_distinct_values(int k, const std::set<T> &forbidden_values) const {
1404 for (auto forbidden : forbidden_values)
1405 tgen_ensure(value_l_ <= forbidden and forbidden <= value_r_);
1406 // We generate our numbers in the range [0, num_available) with
1407 // num_available = (r-l+1)-(forbidden_values.size()), and then map them
1408 // to the correct range. We will run k steps of Fisher–Yates, using a
1409 // map to store a virtual list that starts with a[i] = i.
1410 T num_available = (value_r_ - value_l_ + 1) - forbidden_values.size();
1411 if (num_available < k)
1412 throw detail::complex_restrictions_error(
1413 "list", "not enough distinct values");
1414 std::map<T, T> virtual_list;
1415 std::vector<T> gen_list;
1416 for (int i = 0; i < k; ++i) {
1417 T j = next<T>(i, num_available - 1);
1418 T vj = virtual_list.count(j) ? virtual_list[j] : j;
1419 T vi = virtual_list.count(i) ? virtual_list[i] : i;
1420
1421 virtual_list[j] = vi, virtual_list[i] = vj;
1422
1423 gen_list.push_back(virtual_list[i]);
1424 }
1425
1426 // Shifts back to correct range, but there might still be values
1427 // that we can not use.
1428 for (T &val : gen_list)
1429 val += value_l_;
1430
1431 // Now for every generated value, we shift it by how many forbidden
1432 // values are <= to it.
1433 std::vector<std::pair<T, int>> values_sorted;
1434 for (std::size_t i = 0; i < gen_list.size(); ++i)
1435 values_sorted.emplace_back(gen_list[i], i);
1436 // We iterate through them in increasing order.
1437 std::sort(values_sorted.begin(), values_sorted.end());
1438 auto cur_it = forbidden_values.begin();
1439 int smaller_forbidden_count = 0;
1440 for (auto [val, idx] : values_sorted) {
1441 while (cur_it != forbidden_values.end() and
1442 *cur_it <= val + smaller_forbidden_count)
1443 ++cur_it, ++smaller_forbidden_count;
1444 gen_list[idx] += smaller_forbidden_count;
1445 }
1446
1447 return gen_list;
1448 }
1449
1450 // Generates list value.
1451 // O(n log n).
1452 value gen() const {
1453 std::vector<T> vec(size_);
1454 std::vector<bool> defined_idx(
1455 size_, false); // For every index, if it has been set in `vec`.
1456
1457 std::vector<int> comp_id(size_, -1); // Component id of each index.
1458 std::vector<std::vector<int>> comp(size_); // Component of each comp-id.
1459 int comp_count = 0; // Number of different components.
1460
1461 // Defines value of entire component.
1462 auto define_comp = [&](int cur_comp, T val) {
1463 for (int idx : comp[cur_comp]) {
1464 tgen_ensure(!defined_idx[idx]);
1465 vec[idx] = val;
1466 defined_idx[idx] = true;
1467 }
1468 };
1469
1470 // Groups = components.
1471 {
1472 std::vector<bool> vis(size_, false); // Visited for each index.
1473 for (int idx = 0; idx < size_; ++idx)
1474 if (!vis[idx]) {
1475 T new_value;
1476 bool value_defined = false;
1477
1478 // BFS to visit the connected component, grouping equal
1479 // values.
1480 std::queue<int> q({idx});
1481 vis[idx] = true;
1482 std::vector<int> component;
1483 while (!q.empty()) {
1484 int cur_idx = q.front();
1485 q.pop();
1486
1487 component.push_back(cur_idx);
1488
1489 // Checks value.
1490 auto [l, r] = val_range_[cur_idx];
1491 if (l == r) {
1492 if (!value_defined) {
1493 // We found the value.
1494 value_defined = true;
1495 new_value = l;
1496 } else if (new_value != l) {
1497 // We found a contradiction
1498 throw detail::contradiction_error(
1499 "list",
1500 "tried to set value to `" +
1501 std::to_string(new_value) +
1502 "`, but it was already set as `" +
1503 std::to_string(l) + "`");
1504 }
1505 }
1506
1507 for (int nxt_idx : neigh_[cur_idx]) {
1508 if (!vis[nxt_idx]) {
1509 vis[nxt_idx] = true;
1510 q.push(nxt_idx);
1511 }
1512 }
1513 }
1514
1515 // Group entire component, checking if value is defined.
1516 for (int cur_idx : component) {
1517 comp_id[cur_idx] = comp_count;
1518 comp[comp_id[cur_idx]].push_back(cur_idx);
1519 }
1520
1521 // Defines value if needed.
1522 if (value_defined)
1523 define_comp(comp_count, new_value);
1524
1525 ++comp_count;
1526 }
1527 }
1528
1529 // Initial parsing of different restrictions.
1530 std::vector<std::set<int>> diff_containing_comp_idx(comp_count);
1531 {
1532 int dist_id = 0;
1533 for (const std::set<int> &diff : diff_restrictions_) {
1534 // Checks if there are too many different values.
1535 if (static_cast<uint64_t>(diff.size() - 1) +
1536 static_cast<uint64_t>(value_l_) >
1537 static_cast<uint64_t>(value_r_))
1538 throw detail::contradiction_error(
1539 "list", "tried to generate " +
1540 std::to_string(diff.size()) +
1541 " different values, but the maximum is " +
1542 std::to_string(value_r_ - value_l_ + 1));
1543
1544 // Checks if two values in same component are marked as
1545 // different.
1546 std::set<int> comp_ids;
1547 for (int idx : diff) {
1548 if (comp_ids.count(comp_id[idx]))
1549 throw detail::contradiction_error(
1550 "list", "tried to set two indices as equal and "
1551 "different");
1552 comp_ids.insert(comp_id[idx]);
1553
1554 diff_containing_comp_idx[comp_id[idx]].insert(dist_id);
1555 }
1556 ++dist_id;
1557 }
1558 }
1559
1560 // If some value is in >= 3 sets, then there is a cycle.
1561 for (auto &diff_containing : diff_containing_comp_idx)
1562 if (diff_containing.size() >= 3)
1563 throw detail::complex_restrictions_error(
1564 "list",
1565 "one index can not be in >= 3 'different' restrictions");
1566
1567 std::vector<bool> vis_diff(diff_restrictions_.size(), false);
1568 std::vector<bool> initially_defined_comp_idx(comp_count, false);
1569
1570 // Fills the value in a tree defined by "different" restrictions.
1571 auto define_tree = [&](int diff_id) {
1572 // The set `diff_restrictions_[diff_id]` can have some
1573 // values that are defined.
1574
1575 // Generates set of already defined values.
1576 std::set<T> defined_values;
1577 for (int idx : diff_restrictions_[diff_id])
1578 if (defined_idx[idx]) {
1579 // Checks if two values in `diff_restrictions_[dist_id]`
1580 // have been set to the same value
1581 if (defined_values.count(vec[idx]))
1582 throw detail::contradiction_error(
1583 "list",
1584 "tried to set two indices as equal and different");
1585
1586 defined_values.insert(vec[idx]);
1587 }
1588
1589 // Generates values in this root "different" restriction.
1590 {
1591 int new_value_count = diff_restrictions_[diff_id].size() -
1592 static_cast<int>(defined_values.size());
1593 std::vector<T> generated_values =
1594 generate_distinct_values(new_value_count, defined_values);
1595 auto val_it = generated_values.begin();
1596 for (int idx : diff_restrictions_[diff_id])
1597 if (defined_idx[idx]) {
1598 // The root can cover these components, but there should
1599 // not be any other defined in this tree.
1600 initially_defined_comp_idx[comp_id[idx]] = false;
1601 } else {
1602 define_comp(comp_id[idx], *val_it);
1603 ++val_it;
1604 }
1605 }
1606
1607 // BFS on the tree of "different" restrictions.
1608 std::queue<std::pair<int, int>> q; // {id, parent id}
1609 q.emplace(diff_id, -1);
1610 vis_diff[diff_id] = true;
1611 while (!q.empty()) {
1612 auto [cur_diff, parent] = q.front();
1613 q.pop();
1614
1615 std::set<int> neigh_diff;
1616 for (int idx : diff_restrictions_[cur_diff])
1617 for (int nxt_diff :
1618 diff_containing_comp_idx[comp_id[idx]]) {
1619 if (nxt_diff == cur_diff or nxt_diff == parent)
1620 continue;
1621
1622 // Cycle found.
1623 if (vis_diff[nxt_diff])
1624 throw detail::complex_restrictions_error(
1625 "list",
1626 "cycle found in 'different' restrictions");
1627
1628 neigh_diff.insert(nxt_diff);
1629 }
1630
1631 for (int nxt_diff : neigh_diff) {
1632 vis_diff[nxt_diff] = true;
1633 q.emplace(nxt_diff, cur_diff);
1634
1635 // Generates this "different" restriction.
1636 std::set<T> nxt_defined_values;
1637 for (int idx2 : diff_restrictions_[nxt_diff])
1638 if (defined_idx[idx2]) {
1639 // There can not be any more defined. This case is
1640 // when there are values not coverered by a single
1641 // "different" restriction in the tree.
1642 if (initially_defined_comp_idx[comp_id[idx2]])
1643 throw detail::complex_restrictions_error(
1644 "list");
1645
1646 nxt_defined_values.insert(vec[idx2]);
1647 }
1648 int new_value_count =
1649 diff_restrictions_[nxt_diff].size() -
1650 static_cast<int>(nxt_defined_values.size());
1651 std::vector<T> generated_values = generate_distinct_values(
1652 new_value_count, nxt_defined_values);
1653 auto val_it = generated_values.begin();
1654 for (int idx2 : diff_restrictions_[nxt_diff])
1655 if (!defined_idx[idx2]) {
1656 define_comp(comp_id[idx2], *val_it);
1657 ++val_it;
1658 }
1659 }
1660 }
1661 };
1662
1663 // Loops through "different" restrictions, sorts "different"
1664 // restrictions by number of defined components (non-increasing). This
1665 // guarantees that if there is a valid root (that covers all 'defined'),
1666 // we find it.
1667 {
1668 std::vector<std::pair<int, int>> defined_cnt_and_diff_idx;
1669 int dist_id = 0;
1670 for (const std::set<int> &diff : diff_restrictions_) {
1671 int defined_cnt = 0;
1672 for (int idx : diff)
1673 if (defined_idx[idx]) {
1674 ++defined_cnt;
1675 initially_defined_comp_idx[comp_id[idx]] = true;
1676 }
1677 defined_cnt_and_diff_idx.emplace_back(defined_cnt, dist_id);
1678 ++dist_id;
1679 }
1680
1681 std::sort(defined_cnt_and_diff_idx.rbegin(),
1682 defined_cnt_and_diff_idx.rend());
1683 for (auto [defined_cnt, diff_idx] : defined_cnt_and_diff_idx)
1684 if (!vis_diff[diff_idx])
1685 define_tree(diff_idx);
1686 }
1687
1688 // Loops through "different" restrictions do define the rest.
1689 for (std::size_t dist_id = 0; dist_id < diff_restrictions_.size();
1690 ++dist_id)
1691 if (!vis_diff[dist_id])
1692 define_tree(dist_id);
1693
1694 // Define final values. These values all should be random in [l, r], and
1695 // the "different" restrictions have already been processed. However,
1696 // there can be still equality restrictions, so we define entire
1697 // components.
1698 for (int idx = 0; idx < size_; ++idx)
1699 if (!defined_idx[idx])
1700 define_comp(comp_id[idx], next<T>(value_l_, value_r_));
1701
1702 if (!values_.empty()) {
1703 // Needs to fetch the values from the value set.
1704 std::vector<T> value_vec(values_.begin(), values_.end());
1705 for (T &val : vec)
1706 val = value_vec[val];
1707 }
1708
1709 return value(vec);
1710 }
1711};
1712
1713/*******************
1714 * *
1715 * PERMUTATION *
1716 * *
1717 *******************/
1718
1719/*
1720 * Permutation generation.
1721 *
1722 * Permutation are defined always as numbers in [0, n), that is, 0-based.
1723 */
1724
1726 int size_; // Size of permutation.
1727 std::vector<std::pair<int, int>> defs_; // {idx, value}.
1728 std::optional<std::vector<int>> cycle_sizes_; // Cycle sizes.
1729
1730 // Creates generator for permutation of size 'size'.
1731 permutation(int size) : size_(size) {
1732 tgen_ensure(size_ > 0, "permutation: size must be positive");
1733 }
1734
1735 // Restricts permutations for permutation[idx] = val.
1736 permutation &fix(int idx, int val) {
1737 tgen_ensure(0 <= idx and idx < size_,
1738 "permutation: index must be valid");
1739 defs_.emplace_back(idx, val);
1740 return *this;
1741 }
1742
1743 // Restricts permutations for permutation to have cycle sizes.
1744 permutation &cycles(const std::vector<int> &cycle_sizes) {
1746 size_ == std::accumulate(cycle_sizes.begin(), cycle_sizes.end(), 0),
1747 "permutation: cycle sizes must add up to size of permutation");
1748 cycle_sizes_ = cycle_sizes;
1749 return *this;
1750 }
1751 permutation &cycles(const std::initializer_list<int> &cycle_sizes) {
1752 return cycles(std::vector<int>(cycle_sizes));
1753 }
1754
1755 // Permutation value.
1756 // Operations on a value are not random.
1758 using tgen_is_sequential_tag = detail::is_sequential_tag;
1759
1760 using std_type = std::vector<int>; // std type for value.
1761 std::vector<int> vec_; // Permutation.
1762 char sep_; // Separator for printing.
1763 bool add_1_; // If should add 1, for printing.
1764
1765 value(const std::vector<int> &vec)
1766 : vec_(vec), sep_(' '), add_1_(false) {
1767 tgen_ensure(!vec_.empty(), "permutation: value: cannot be empty");
1768 std::vector<bool> vis(vec_.size(), false);
1769 for (int i = 0; i < size(); ++i) {
1770 tgen_ensure(0 <= vec_[i] and
1771 vec_[i] < static_cast<int>(vec_.size()),
1772 "permutation: value: values must be from `0` to "
1773 "`size-1`");
1774 tgen_ensure(!vis[vec_[i]],
1775 "permutation: value: cannot have repeated values");
1776 vis[vec_[i]] = true;
1777 }
1778 }
1779 value(const std::initializer_list<int> &il)
1780 : value(std::vector<int>(il)) {}
1781
1782 // Fetches size.
1783 int size() const { return vec_.size(); }
1784
1785 // Fetches position idx.
1786 const int &operator[](int idx) const {
1787 tgen_ensure(0 <= idx and idx < size(),
1788 "permutation: value: index out of bounds");
1789 return vec_[idx];
1790 }
1791
1792 // Returns parity of the permutation (+1 if even, -1 if odd).
1793 // O(n).
1794 int parity() const {
1795 std::vector<bool> vis(size(), false);
1796 int cycles = 0;
1797
1798 for (int i = 0; i < size(); ++i)
1799 if (!vis[i]) {
1800 cycles++;
1801 for (int j = i; !vis[j]; j = vec_[j])
1802 vis[j] = true;
1803 }
1804 // Even iff (n - cycles) is even.
1805 return ((size() - cycles) % 2 == 0) ? +1 : -1;
1806 }
1807
1808 // Sorts values in increasign order.
1809 // O(n).
1811 for (int i = 0; i < size(); ++i)
1812 vec_[i] = i;
1813 return *this;
1814 }
1815
1816 // Reverses permutation.
1817 // O(n).
1819 std::reverse(vec_.begin(), vec_.end());
1820 return *this;
1821 }
1822
1823 // Inverse of the permutation.
1824 // O(n).
1826 std::vector<int> inv(size());
1827 for (int i = 0; i < size(); ++i)
1828 inv[vec_[i]] = i;
1829 swap(vec_, inv);
1830 return *this;
1831 }
1832
1833 // Sets the separator, for printing.
1834 // O(1).
1835 value &separator(char sep) {
1836 sep_ = sep;
1837 return *this;
1838 }
1839
1840 // Sets that should print values 1-based.
1841 // O(1).
1843 add_1_ = true;
1844 return *this;
1845 }
1846
1847 // Prints to std::ostream, separated by sep_.
1848 friend std::ostream &operator<<(std::ostream &out, const value &inst) {
1849 for (int i = 0; i < inst.size(); ++i) {
1850 if (i > 0)
1851 out << inst.sep_;
1852 out << inst[i] + inst.add_1_;
1853 }
1854 return out;
1855 }
1856
1857 // Gets a std::vector representing the value.
1858 std::vector<int> to_std() const { return vec_; }
1859 };
1860
1861 // Generates permutation value.
1862 // O(n).
1863 value gen() const {
1864 if (!cycle_sizes_) {
1865 // Cycle sizes not specified.
1866 std::vector<int> idx_to_val(size_, -1), val_to_idx(size_, -1);
1867 for (auto [idx, val] : defs_) {
1869 0 <= val and val < size_,
1870 "permutation: value in permutation must be in [0, " +
1871 std::to_string(size_) + ")");
1872
1873 if (idx_to_val[idx] != -1) {
1874 tgen_ensure(idx_to_val[idx] == val,
1875 "permutation: cannot set an idex to two "
1876 "different values");
1877 } else
1878 idx_to_val[idx] = val;
1879
1880 if (val_to_idx[val] != -1) {
1881 tgen_ensure(val_to_idx[val] == idx,
1882 "permutation: cannot set two indices to the "
1883 "same value");
1884 } else
1885 val_to_idx[val] = idx;
1886 }
1887
1888 std::vector<int> perm(size_);
1889 std::iota(perm.begin(), perm.end(), 0);
1890 shuffle(perm.begin(), perm.end());
1891 int cur_idx = 0;
1892 for (int &i : idx_to_val)
1893 if (i == -1) {
1894 // While this value is used, skip.
1895 while (val_to_idx[perm[cur_idx]] != -1)
1896 ++cur_idx;
1897 i = perm[cur_idx++];
1898 }
1899 return idx_to_val;
1900 }
1901
1902 // Creates cycles.
1903 std::vector<int> order(size_);
1904 std::iota(order.begin(), order.end(), 0);
1905 shuffle(order.begin(), order.end());
1906 int idx = 0;
1907 std::vector<std::vector<int>> cycles;
1908 for (int cycle_size : *cycle_sizes_) {
1909 cycles.emplace_back();
1910 for (int i = 0; i < cycle_size; ++i)
1911 cycles.back().push_back(order[idx++]);
1912 }
1913
1914 // Retrieves permutation from cycles.
1915 std::vector<int> perm(size_, -1);
1916 for (const std::vector<int> &cycle : cycles) {
1917 int cur_size = cycle.size();
1918 for (int i = 0; i < cur_size; ++i)
1919 perm[cycle[i]] = cycle[(i + 1) % cur_size];
1920 }
1921
1922 return value(perm);
1923 }
1924};
1925
1926/************
1927 * *
1928 * MATH *
1929 * *
1930 ************/
1931
1932namespace math {
1933
1934namespace detail {
1935
1936using namespace tgen::detail;
1937
1938inline int popcount(uint64_t x) { return __builtin_popcountll(x); }
1939
1940inline int ctzll(uint64_t x) {
1941 // Mistery code found on the internet.
1942 // Uses de Brujin sequence.
1943 static const unsigned char index64[64] = {
1944 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
1945 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
1946 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
1947 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12};
1948 return index64[((x & -x) * 0x022FDD63CC95386D) >> 58];
1949}
1950
1951inline uint64_t mul_mod(uint64_t a, uint64_t b, uint64_t m) {
1952 return static_cast<u128>(a) * b % m;
1953}
1954
1955// O(log n).
1956// 0 <= x < m.
1957inline uint64_t expo_mod(uint64_t x, uint64_t y, uint64_t m) {
1958 if (!y)
1959 return 1;
1960 uint64_t ans = expo_mod(mul_mod(x, x, m), y / 2, m);
1961 return y % 2 ? mul_mod(x, ans, m) : ans;
1962}
1963
1964} // namespace detail
1965
1966// O(log^2 n).
1967inline bool is_prime(uint64_t n) {
1968 if (n < 2)
1969 return false;
1970 if (n == 2 or n == 3)
1971 return true;
1972 if (n % 2 == 0)
1973 return false;
1974
1975 uint64_t r = detail::ctzll(n - 1), d = n >> r;
1976 // These bases are guaranteed to work for n <= 2^64.
1977 for (int a : {2, 325, 9375, 28178, 450775, 9780504, 1795265022}) {
1978 uint64_t x = detail::expo_mod(a, d, n);
1979 if (x == 1 or x == n - 1 or a % n == 0)
1980 continue;
1981
1982 for (uint64_t j = 0; j < r - 1; ++j) {
1983 x = detail::mul_mod(x, x, n);
1984 if (x == n - 1)
1985 break;
1986 }
1987 if (x != n - 1)
1988 return false;
1989 }
1990 return true;
1991}
1992
1993namespace detail {
1994
1995inline uint64_t pollard_rho(uint64_t n) {
1996 if (n == 1 or is_prime(n))
1997 return n;
1998 auto f = [n](uint64_t x) { return mul_mod(x, x, n) + 1; };
1999
2000 uint64_t x = 0, y = 0, t = 30, prd = 2, x0 = 1, q;
2001 while (t % 40 != 0 or std::gcd(prd, n) == 1) {
2002 if (x == y)
2003 x = ++x0, y = f(x);
2004 q = mul_mod(prd, x > y ? x - y : y - x, n);
2005 if (q != 0)
2006 prd = q;
2007 x = f(x), y = f(f(y)), t++;
2008 }
2009 return std::gcd(prd, n);
2010}
2011
2012inline std::vector<uint64_t> factor(uint64_t n) {
2013 if (n == 1)
2014 return {};
2015 if (is_prime(n))
2016 return {n};
2017 uint64_t d = pollard_rho(n);
2018 std::vector<uint64_t> l = factor(d), r = factor(n / d);
2019 l.insert(l.end(), r.begin(), r.end());
2020 return l;
2021}
2022
2023// Error handling.
2024template <typename T>
2025std::runtime_error there_is_no_in_range_error(const std::string &type, T l,
2026 T r) {
2027 return error("math: there is no " + type + " in range [" +
2028 std::to_string(l) + ", " + std::to_string(r) + "]");
2029}
2030template <typename T>
2031std::runtime_error there_is_no_from_error(const std::string &type, T r) {
2032 return error("math: there is no " + type + " from " + std::to_string(r));
2033}
2034template <typename T>
2035std::runtime_error there_is_no_upto_error(const std::string &type, T r) {
2036 return error("math: there is no " + type + " up to " + std::to_string(r));
2037}
2038
2039// O(log mod).
2040// 0 < a < mod.
2041// gcd(a, mod) = 1.
2042inline i128 modular_inverse_128(i128 a, i128 mod) {
2043 tgen_ensure(0 < a and a < mod,
2044 "math: remainder must be positive and smaller than the mod");
2045
2046 i128 t = 0, new_t = 1;
2047 i128 r = mod, new_r = a;
2048
2049 while (new_r != 0) {
2050 i128 q = r / new_r;
2051
2052 auto tmp_t = t - q * new_t;
2053 t = new_t;
2054 new_t = tmp_t;
2055
2056 auto tmp_r = r - q * new_r;
2057 r = new_r;
2058 new_r = tmp_r;
2059 }
2060
2061 tgen_ensure(r == 1, "math: remainder and mod must be coprime");
2062
2063 if (t < 0)
2064 t += mod;
2065 return t;
2066}
2067
2068// checks if a * b <= limit, for positive numbers.
2069inline bool mul_leq(uint64_t a, uint64_t b, uint64_t limit) {
2070 if (a == 0)
2071 return true;
2072 return a <= limit / b;
2073}
2074
2075// base^exp, or null if base^exp > limit.
2076inline std::optional<uint64_t> expo(uint64_t base, uint64_t exp,
2077 uint64_t limit) {
2078 uint64_t result = 1;
2079
2080 while (exp) {
2081 if (exp & 1) {
2082 if (!mul_leq(result, base, limit))
2083 return std::nullopt;
2084 result *= base;
2085 }
2086
2087 exp >>= 1;
2088 // Necesary for correctness.
2089 if (!exp)
2090 break;
2091
2092 if (!mul_leq(base, base, limit))
2093 return std::nullopt;
2094 base *= base;
2095 }
2096 return result;
2097}
2098
2099// O(log n log k).
2100// 0 < k.
2101inline uint64_t kth_root_floor(uint64_t n, uint64_t k) {
2102 tgen_ensure_against_bug(k > 0, "math: value must be valid");
2103 if (k == 1 or n <= 1)
2104 return n;
2105
2106 uint64_t lo = 1, hi = 1ULL << ((64 + k - 1) / k);
2107
2108 while (lo < hi) {
2109 uint64_t mid = lo + (hi - lo + 1) / 2;
2110
2111 if (expo(mid, k, n)) {
2112 lo = mid;
2113 } else {
2114 hi = mid - 1;
2115 }
2116 }
2117 return lo;
2118}
2119
2120// gcd(a, b).
2121// O(log a).
2122inline i128 gcd128(i128 a, i128 b) {
2123 if (a < 0)
2124 a = -a;
2125 if (b < 0)
2126 b = -b;
2127 while (b != 0) {
2128 i128 t = a % b;
2129 a = b;
2130 b = t;
2131 }
2132 return a;
2133}
2134
2135// min(2^64, a*b).
2136// O(log a).
2137// a, b >= 0.
2138inline i128 mul_saturate(i128 a, i128 b) {
2139 tgen_ensure(a >= 0 and b >= 0);
2140 static const i128 LIMIT = static_cast<i128>(1) << 64;
2141 if (a == 0 or b == 0)
2142 return 0;
2143 if (a > LIMIT / b)
2144 return LIMIT;
2145 return a * b;
2146}
2147
2148struct crt {
2149 using T = i128;
2150 T a, m;
2151
2152 crt() : a(0), m(1) {}
2153 crt(T a_, T m_) : a(a_), m(m_) {}
2154 crt operator*(crt C) {
2155 if (m == 0 or C.m == 0)
2156 return {-1, 0};
2157
2158 T g = gcd128(m, C.m);
2159 if ((C.a - a) % g != 0)
2160 return {-1, 0};
2161
2162 T m1 = m / g;
2163 T m2 = C.m / g;
2164
2165 if (m2 == 1)
2166 return {a, m};
2167
2168 T inv = modular_inverse_128(m1 % m2, m2);
2169
2170 T k = ((C.a - a) / g) % m2;
2171 if (k < 0)
2172 k += m2;
2173
2174 k = static_cast<u128>(k) * inv % m2;
2175
2176 T lcm = mul_saturate(m, m2);
2177
2178 T res = (a + static_cast<T>((static_cast<u128>(k) * m) % lcm)) % lcm;
2179 if (res < 0)
2180 res += lcm;
2181
2182 return {res, lcm};
2183 }
2184};
2185
2186// Math hacks to operate on log space.
2187
2188inline constexpr long double LOG_ZERO = -INFINITY;
2189inline constexpr long double LOG_ONE = 0.0;
2190
2191inline long double log_space(long double x) {
2192 return x == 0.0 ? LOG_ZERO : std::log(x);
2193}
2194
2195// Math hack to add two values in log space.
2196inline long double add_log_space(long double a, long double b) {
2197 if (a == LOG_ZERO)
2198 return b;
2199 if (b == LOG_ZERO)
2200 return a;
2201 if (a < b)
2202 std::swap(a, b);
2203 if (b == LOG_ZERO)
2204 return a;
2205 return a + log1p(exp(b - a));
2206}
2207
2208// Math hack to subtract two values in log space.
2209// a >= b.
2210inline long double sub_log_space(long double a, long double b) {
2211 if (b >= a)
2212 return LOG_ZERO;
2213 if (b == LOG_ZERO)
2214 return a;
2215 return a + log1p(-exp(b - a));
2216}
2217
2218} // namespace detail
2219
2220// Sorted.
2221// O(n^(1/4) log n) expected.
2222// 0 < n.
2223inline std::vector<uint64_t> factor(uint64_t n) {
2224 tgen_ensure(n > 0, "math: number to factor must be positive");
2225 auto factors = detail::factor(n);
2226 std::sort(factors.begin(), factors.end());
2227 return factors;
2228}
2229
2230// Sorted.
2231// O(n^(1/4) log n) expected.
2232// 0 < n.
2233inline std::vector<std::pair<uint64_t, int>> factor_by_prime(uint64_t n) {
2234 tgen_ensure(n > 0, "math: number to factor must be positive");
2235 std::vector<std::pair<uint64_t, int>> primes;
2236 for (uint64_t p : factor(n)) {
2237 if (!primes.empty() and primes.back().first == p)
2238 ++primes.back().second;
2239 else
2240 primes.emplace_back(p, 1);
2241 }
2242 return primes;
2243}
2244
2245// O(log mod).
2246// 0 < a < mod.
2247// gcd(a, mod) = 1.
2248inline uint64_t modular_inverse(uint64_t a, uint64_t mod) {
2249 return detail::modular_inverse_128(a, mod);
2250}
2251
2252// O(n^(1/4) log n) expected.
2253// 0 < n.
2254inline uint64_t totient(uint64_t n) {
2255 tgen_ensure(n > 0, "math: totient(0) is undefined");
2256 uint64_t phi = n;
2257
2258 for (auto [p, e] : factor_by_prime(n))
2259 phi -= phi / p;
2260
2261 return phi;
2262}
2263
2264// Returns `(p_i, g_i)`: `p_i` is the prime, `g_i` is the gap.
2265inline const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> &
2266prime_gaps() {
2267 // From https://en.wikipedia.org/wiki/Prime_gap.
2268 static const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> value{
2269 /* clang-format off */ {
2270 2, 3, 7, 23, 89, 113, 523, 887, 1129, 1327, 9551, 15683, 19609,
2271 31397, 155921, 360653, 370261, 492113, 1349533, 1357201, 2010733,
2272 4652353, 17051707, 20831323, 47326693, 122164747, 189695659,
2273 191912783, 387096133, 436273009, 1294268491, 1453168141,
2274 2300942549, 3842610773, 4302407359, 10726904659, 20678048297,
2275 22367084959, 25056082087, 42652618343, 127976334671, 182226896239,
2276 241160624143, 297501075799, 303371455241, 304599508537,
2277 416608695821, 461690510011, 614487453523, 738832927927,
2278 1346294310749, 1408695493609, 1968188556461, 2614941710599,
2279 7177162611713, 13829048559701, 19581334192423, 42842283925351,
2280 90874329411493, 171231342420521, 218209405436543, 1189459969825483,
2281 1686994940955803, 1693182318746371, 43841547845541059,
2282 55350776431903243, 80873624627234849, 203986478517455989,
2283 218034721194214273, 305405826521087869, 352521223451364323,
2284 401429925999153707, 418032645936712127, 804212830686677669,
2285 1425172824437699411, 5733241593241196731, 6787988999657777797
2286 }, /* clang-format on */
2287 {1, 2, 4, 6, 8, 14, 18, 20, 22, 34, 36,
2288 44, 52, 72, 86, 96, 112, 114, 118, 132, 148, 154,
2289 180, 210, 220, 222, 234, 248, 250, 282, 288, 292, 320,
2290 336, 354, 382, 384, 394, 456, 464, 468, 474, 486, 490,
2291 500, 514, 516, 532, 534, 540, 582, 588, 602, 652, 674,
2292 716, 766, 778, 804, 806, 906, 916, 924, 1132, 1184, 1198,
2293 1220, 1224, 1248, 1272, 1328, 1356, 1370, 1442, 1476, 1488, 1510}};
2294
2295 return value;
2296}
2297
2298// Returns pair (first_composite_in_gap, last_composite_in_gap).
2299// O(log(right)) approximately.
2300inline std::pair<uint64_t, uint64_t> prime_gap_upto(uint64_t right) {
2301 if (right < 4)
2302 throw detail::there_is_no_upto_error("prime gap", right);
2303
2304 const auto &[P, G] = prime_gaps();
2305 for (int i = P.size() - 1;; --i) {
2306 if (P[i] >= right)
2307 continue;
2308
2309 uint64_t real_right = std::min(right, P[i] + G[i] - 1);
2310 uint64_t prev = i > 0 ? G[i - 1] : 0;
2311 uint64_t curr = real_right - P[i];
2312
2313 if (curr >= prev)
2314 return {P[i] + 1, real_right};
2315 }
2316}
2317
2318// From https://oeis.org/A002182/b002182.txt.
2320 /* clang-format off */
2321 static const std::vector<uint64_t> highly_composites = {
2322 1, 2, 4, 6, 12, 24, 36, 48, 60, 120, 180, 240, 360, 720, 840, 1260, 1680,
2323 2520, 5040, 7560, 10080, 15120, 20160, 25200, 27720, 45360, 50400, 55440,
2324 83160, 110880, 166320, 221760, 277200, 332640, 498960, 554400, 665280,
2325 720720, 1081080, 1441440, 2162160, 2882880, 3603600, 4324320, 6486480,
2326 7207200, 8648640, 10810800, 14414400, 17297280, 21621600, 32432400,
2327 36756720, 43243200, 61261200, 73513440, 110270160, 122522400, 147026880,
2328 183783600, 245044800, 294053760, 367567200, 551350800, 698377680, 735134400,
2329 1102701600, 1396755360, 2095133040, 2205403200, 2327925600, 2793510720,
2330 3491888400, 4655851200, 5587021440, 6983776800, 10475665200, 13967553600,
2331 20951330400, 27935107200, 41902660800, 48886437600, 64250746560,
2332 73329656400, 80313433200, 97772875200, 128501493120, 146659312800,
2333 160626866400, 240940299600, 293318625600, 321253732800, 481880599200,
2334 642507465600, 963761198400, 1124388064800, 1606268664000, 1686582097200,
2335 1927522396800, 2248776129600, 3212537328000, 3373164194400, 4497552259200,
2336 6746328388800, 8995104518400, 9316358251200, 13492656777600, 18632716502400,
2337 26985313555200, 27949074753600, 32607253879200, 46581791256000,
2338 48910880818800, 55898149507200, 65214507758400, 93163582512000,
2339 97821761637600, 130429015516800, 195643523275200, 260858031033600,
2340 288807105787200, 391287046550400, 577614211574400, 782574093100800,
2341 866421317361600, 1010824870255200, 1444035528936000, 1516237305382800,
2342 1732842634723200, 2021649740510400, 2888071057872000, 3032474610765600,
2343 4043299481020800, 6064949221531200, 8086598962041600, 10108248702552000,
2344 12129898443062400, 18194847664593600, 20216497405104000, 24259796886124800,
2345 30324746107656000, 36389695329187200, 48519593772249600, 60649492215312000,
2346 72779390658374400, 74801040398884800, 106858629141264000,
2347 112201560598327200, 149602080797769600, 224403121196654400,
2348 299204161595539200, 374005201994424000, 448806242393308800,
2349 673209363589963200, 748010403988848000, 897612484786617600,
2350 1122015605983272000, 1346418727179926400, 1795224969573235200,
2351 2244031211966544000, 2692837454359852800, 3066842656354276800,
2352 4381203794791824000, 4488062423933088000, 6133685312708553600,
2353 8976124847866176000, 9200527969062830400, 12267370625417107200ULL,
2354 15334213281771384000ULL, 18401055938125660800ULL}; /* clang-format on */
2355 return highly_composites;
2356}
2357
2358// O(log(right)) approximately.
2359inline uint64_t highly_composite_upto(uint64_t right) {
2360 for (int i = highly_composites().size() - 1; i >= 0; --i)
2361 if (highly_composites()[i] <= right)
2362 return highly_composites()[i];
2363
2364 throw detail::there_is_no_upto_error("highly composite number", right);
2365}
2366
2367// O(log^3 (right)) expected.
2368// Generates a random prime in [left, right].
2369inline uint64_t gen_prime(uint64_t left, uint64_t right) {
2370 if (right < left or right < 2)
2371 throw detail::there_is_no_in_range_error("prime", left, right);
2372 left = std::max<uint64_t>(left, 2);
2373 auto [l_gap, r_gap] = prime_gap_upto(right);
2374 if (right - left + 1 <= r_gap - l_gap + 1) {
2375 // There might be no primes in the range.
2376 std::vector<uint64_t> vals(right - left + 1);
2377 iota(vals.begin(), vals.end(), left);
2378 shuffle(vals.begin(), vals.end());
2379 for (uint64_t i : vals)
2380 if (is_prime(i))
2381 return i;
2382 throw detail::there_is_no_in_range_error("prime", left, right);
2383 }
2384
2385 uint64_t n;
2386 do {
2387 n = next(left, right);
2388 } while (!is_prime(n));
2389 return n;
2390}
2391
2392// O(log^3 (left)) expected.
2393// left <= 2^64 - 59.
2394inline uint64_t prime_from(uint64_t left) {
2395 tgen_ensure(left <= std::numeric_limits<uint64_t>::max() - 58,
2396 "math: invalid bound");
2397 for (uint64_t i = std::max<uint64_t>(2, left);; ++i)
2398 if (is_prime(i))
2399 return i;
2400}
2401
2402// O(log^3 (right)) expected.
2403inline uint64_t prime_upto(uint64_t right) {
2404 if (right >= 2)
2405 for (uint64_t i = right; i >= 2; --i)
2406 if (is_prime(i))
2407 return i;
2408 throw detail::there_is_no_upto_error("prime", right);
2409}
2410
2411// O(n^(1/4) log n) expected.
2412// 0 < n.
2413inline int num_divisors(uint64_t n) {
2414 int divisors = 1;
2415 for (auto [p, e] : factor_by_prime(n))
2416 divisors *= (e + 1);
2417 return divisors;
2418}
2419
2420// Random number in [left, right] with `divisor_count` divisors.
2421// O(log(right) log(divisor_count)).
2422// divisor_count must be prime.
2423inline uint64_t gen_divisor_count(uint64_t left, uint64_t right,
2424 int divisor_count) {
2425 tgen_ensure(divisor_count > 0 and is_prime(divisor_count),
2426 "math: divisor count must be prime");
2427 int root = divisor_count - 1;
2428 uint64_t p = gen_prime(detail::kth_root_floor(left, root),
2429 detail::kth_root_floor(right, root));
2430 return *detail::expo(p, root, right);
2431}
2432
2433// O(|mods| + log (right)).
2434// |rems| = |mods|.
2435// rems_i < mods_i.
2436inline uint64_t gen_congruent(uint64_t left, uint64_t right,
2437 std::vector<uint64_t> rems,
2438 std::vector<uint64_t> mods) {
2439 if (left > right)
2440 throw detail::there_is_no_in_range_error("congruent number", left,
2441 right);
2442 tgen_ensure(rems.size() == mods.size(),
2443 "math: number of remainders and mods must be the same");
2444 tgen_ensure(rems.size() > 0, "math: must have at least one congruence");
2445
2446 detail::crt crt;
2447 for (int i = 0; i < static_cast<int>(rems.size()); ++i) {
2448 tgen_ensure(rems[i] < mods[i],
2449 "math: remainder must be smaller than the mod");
2450 crt = crt * detail::crt(rems[i], mods[i]);
2451
2452 if (crt.a == -1)
2453 throw detail::there_is_no_in_range_error("congruent number", left,
2454 right);
2455 if (crt.m > right) {
2456 if (!(left <= crt.a and crt.a <= right))
2457 throw detail::there_is_no_in_range_error("congruent number",
2458 left, right);
2459
2460 for (int j = 0; j < static_cast<int>(rems.size()); ++j)
2461 if (crt.a % mods[j] != rems[j])
2462 throw detail::there_is_no_in_range_error("congruent number",
2463 left, right);
2464 return crt.a;
2465 }
2466 }
2467
2468 uint64_t k_min = crt.a >= left ? 0 : ((left - crt.a) + crt.m - 1) / crt.m;
2469 uint64_t k_max = (right - crt.a) / crt.m;
2470
2471 if (k_min > k_max)
2472 throw detail::there_is_no_in_range_error("congruent number", left,
2473 right);
2474
2475 return crt.a + next(k_min, k_max) * crt.m;
2476}
2477
2478// O(log (right)).
2479// rem < mod.
2480inline uint64_t gen_congruent(uint64_t left, uint64_t right, uint64_t rem,
2481 uint64_t mod) {
2482 return gen_congruent(left, right, std::vector<uint64_t>({rem}),
2483 std::vector<uint64_t>({mod}));
2484}
2485
2486// First congruent number >= left.
2487// O(|mods| + log (left)).
2488// |rems| = |mods|.
2489// rems_i < mods_i.
2490inline uint64_t congruent_from(uint64_t left, std::vector<uint64_t> rems,
2491 std::vector<uint64_t> mods) {
2492 tgen_ensure(rems.size() == mods.size(),
2493 "math: number of remainders and mods must be the same");
2494 tgen_ensure(rems.size() > 0, "math: must have at least one congruence");
2495
2496 detail::crt crt;
2497 for (int i = 0; i < static_cast<int>(rems.size()); ++i) {
2498 tgen_ensure(rems[i] < mods[i],
2499 "math: remainder must be smaller than the mod");
2500 crt = crt * detail::crt(rems[i], mods[i]);
2501
2502 if (crt.a == -1)
2503 throw detail::there_is_no_from_error("congruent number", left);
2504 if (crt.m > std::numeric_limits<uint64_t>::max()) {
2505 if (crt.a < left)
2506 throw detail::error(
2507 "math: congruent number does not exist or is too large");
2508
2509 for (int j = 0; j < static_cast<int>(rems.size()); ++j)
2510 if (crt.a % mods[j] != rems[j])
2511 throw detail::error("math: congruent number does "
2512 "not exist or is too large");
2513 return crt.a;
2514 }
2515 }
2516
2517 uint64_t k = 0;
2518 if (crt.a < left)
2519 k = ((left - crt.a) + crt.m - 1) / crt.m;
2520 detail::i128 result = crt.a + k * crt.m;
2521
2522 if (result > std::numeric_limits<uint64_t>::max())
2523 throw detail::error("math: congruent number is too large");
2524 return static_cast<uint64_t>(result);
2525}
2526
2527// O(log (left))
2528// rem < mod.
2529inline uint64_t congruent_from(uint64_t left, uint64_t rem, uint64_t mod) {
2530 return congruent_from(left, std::vector<uint64_t>{rem},
2531 std::vector<uint64_t>{mod});
2532}
2533
2534// Last congruent number <= right.
2535// O(|mods| + log (right)).
2536// |rems| = |mods|.
2537// rems_i < mods_i.
2538inline uint64_t congruent_upto(uint64_t right, std::vector<uint64_t> rems,
2539 std::vector<uint64_t> mods) {
2540 tgen_ensure(rems.size() == mods.size(),
2541 "math: number of remainders and mods must be the same");
2542 tgen_ensure(rems.size() > 0, "math: must have at least one congruence");
2543
2544 detail::crt crt;
2545 for (int i = 0; i < static_cast<int>(rems.size()); ++i) {
2546 tgen_ensure(rems[i] < mods[i],
2547 "math: remainder must be smaller than the mod");
2548
2549 crt = crt * detail::crt(rems[i], mods[i]);
2550
2551 if (crt.a == -1)
2552 throw detail::there_is_no_upto_error("congruent number", right);
2553 if (crt.m > right) {
2554 if (!(crt.a <= right))
2555 throw detail::there_is_no_upto_error("congruent number", right);
2556
2557 for (int j = 0; j < static_cast<int>(rems.size()); ++j)
2558 if (crt.a % mods[j] != rems[j])
2559 throw detail::there_is_no_upto_error("congruent number",
2560 right);
2561 return crt.a;
2562 }
2563 }
2564
2565 if (crt.a > right)
2566 throw detail::there_is_no_upto_error("congruent number", right);
2567
2568 uint64_t k = (right - crt.a) / crt.m;
2569 detail::i128 result = crt.a + k * crt.m;
2570
2571 if (result < 0)
2572 throw detail::there_is_no_upto_error("congruent number", right);
2573 return static_cast<uint64_t>(result);
2574}
2575
2576// O(log r)
2577// rem < mod.
2578inline uint64_t congruent_upto(uint64_t right, uint64_t rem, uint64_t mod) {
2579 return congruent_upto(right, std::vector<uint64_t>{rem},
2580 std::vector<uint64_t>{mod});
2581}
2582
2583// Mod used for FFT/NTT.
2584inline constexpr int FFT_MOD = 998244353;
2585
2586// Fibonacci sequence up to 2^64.
2587inline const std::vector<uint64_t> &fibonacci() {
2588 static const std::vector<uint64_t> fib = [] {
2589 std::vector<uint64_t> v = {0, 1};
2590 while (v.back() <=
2591 std::numeric_limits<uint64_t>::max() - v[v.size() - 2])
2592 v.push_back(v.back() + v[v.size() - 2]);
2593 return v;
2594 }();
2595 return fib;
2596}
2597
2598// Parition is ordered (composition), that is, (1, 1, 2) != (1, 2, 1).
2599// O(n).
2600// 0 < n.
2601// 0 < part_left.
2602inline std::vector<int>
2603gen_partition(int n, int part_left = 1,
2604 std::optional<int> part_right = std::nullopt) {
2605 if (!part_right)
2606 part_right = n;
2607 part_right = std::min(*part_right, n);
2608 tgen_ensure(n > 0 and part_left > 0,
2609 "math: invalid parameters to gen_partition");
2610 tgen_ensure(part_left <= n and *part_right > 0, "math: no such partition");
2611
2612 // dp[i] = log(numbers of ways to add to i).
2613 std::vector<long double> dp(n + 1, detail::LOG_ZERO);
2614 dp[0] = detail::LOG_ONE;
2615 long double window = detail::LOG_ZERO;
2616 for (int i = 1; i <= n; ++i) {
2617 if (i >= part_left)
2618 window = detail::add_log_space(window, dp[i - part_left]);
2619 if (i >= *part_right + 1)
2620 window = detail::sub_log_space(window, dp[i - *part_right - 1]);
2621 dp[i] = window;
2622 }
2623 tgen_ensure(dp[n] >= 0, "math: no such partition");
2624
2625 // Crazy math tricks ahead.
2626 auto dp_pref = dp;
2627 for (int i = 1; i <= n; ++i)
2628 dp_pref[i] = detail::add_log_space(dp_pref[i - 1], dp[i]);
2629
2630 std::vector<int> part;
2631 int sum = n;
2632 while (sum > 0) {
2633 // Will generate a number such that what remains is in [l, r].
2634 int l = std::max(0, sum - *part_right), r = sum - part_left;
2635 detail::tgen_ensure_against_bug(r >= 0, "math: r < 0 in gen_partition");
2636
2637 int nxt_sum = std::min(sum, r);
2638 long double random = next<long double>(0, 1);
2639
2640 // We generate a value X (log space), and then choose nxt_sum such
2641 // that dp_pref[nxt_sum-1] < X <= dp_pref[nxt_sum].
2642
2643 // Math hack:
2644 // Let A = pref[l-1], B = pref[r], U = rand().
2645 // X = log[exp(A) + U * (exp(B) - exp(A))]
2646 // = log{exp(B) * [exp(A) / exp(B) + U * (1 - exp(A) / exp(B))]}
2647 // = B + log[exp(A - B) + U - U * exp(A - B))]
2648 // = B + log[U + (1 - U) * exp(A - B)].
2649 long double val_l = l ? dp_pref[l - 1] : detail::LOG_ZERO,
2650 val_r = dp_pref[r];
2651 while (nxt_sum > l and
2652 dp_pref[nxt_sum - 1] >=
2653 val_r + detail::log_space(random +
2654 (1 - random) * exp(val_l - val_r)))
2655 --nxt_sum;
2656
2657 part.push_back(sum - nxt_sum);
2658 sum = nxt_sum;
2659 }
2660
2661 return part;
2662}
2663
2664// Parition is ordered (composition), that is, (1, 1, 2) != (1, 2, 1).
2665// O(n) time/memory if part_r is not set, O(n * k) time/memory otherwise.
2666// 0 < k <= n.
2667// 0 <= part_left.
2668inline std::vector<int>
2669gen_partition_fixed_size(int n, int k, int part_left = 0,
2670 std::optional<int> part_right = std::nullopt) {
2671 if (!part_right)
2672 part_right = n;
2673 part_right = std::min(*part_right, n);
2674 tgen_ensure(0 < k and k <= n and part_left >= 0,
2675 "math: invalid parameters to gen_partition_fixed_size");
2676 tgen_ensure(static_cast<long long>(k) * part_left <= n and
2677 n <= static_cast<long long>(k) * (*part_right),
2678 "math: no such partition");
2679
2680 // What we need to distribute to the parts.
2681 int s = n - k * part_left;
2682
2683 std::vector<int> part(k);
2684 if (*part_right == n) {
2685 // Stars and bars - O(n).
2686 std::vector<int> cuts = {-1};
2687
2688 int total = s + k - 1, bars = k - 1;
2689 for (int i = 0; i < total and bars > 0; ++i)
2690 if (next<long double>(0, 1) <
2691 static_cast<long double>(bars) / (total - i)) {
2692 cuts.push_back(i);
2693 --bars;
2694 }
2695 cuts.push_back(total);
2696
2697 // Recovers parts.
2698 for (int i = 0; i < k; ++i)
2699 part[i] = cuts[i + 1] - cuts[i] - 1;
2700 } else {
2701 // DP with log trick - O(nk).
2702 int u = *part_right - part_left;
2703
2704 // dp[i][j] = log(#ways to fill i parts with sum j)
2705 std::vector<std::vector<long double>> dp(
2706 k + 1, std::vector<long double>(s + 1, detail::LOG_ZERO));
2707 dp[0][0] = detail::LOG_ONE;
2708
2709 for (int i = 1; i <= k; ++i) {
2710 std::vector<long double> pref = dp[i - 1];
2711 for (int j = 1; j <= s; ++j)
2712 pref[j] = detail::add_log_space(pref[j - 1], dp[i - 1][j]);
2713
2714 for (int j = 0; j <= s; ++j) {
2715 dp[i][j] = pref[j];
2716 if (j >= u + 1)
2717 dp[i][j] = detail::sub_log_space(dp[i][j], pref[j - u - 1]);
2718 }
2719 }
2720
2721 // Recovers parts backwards.
2722 int left_to_distribute = s;
2723 for (int i = k; i >= 1; --i) {
2724 long double log_total = detail::LOG_ZERO;
2725 for (int j = 0; j <= u and j <= left_to_distribute; ++j)
2726 log_total = detail::add_log_space(
2727 log_total, dp[i - 1][left_to_distribute - j]);
2728 detail::tgen_ensure_against_bug(
2729 log_total != detail::LOG_ZERO,
2730 "math: total == 0 in gen_partition_fixed_size");
2731
2732 // Now we choose a number with probability proportional to
2733 // dp[i-1][.].
2734
2735 // log(rand() * total) = log(rand()) + log(total).
2736 long double random =
2737 detail::log_space(next<long double>(0, 1)) + log_total;
2738
2739 long double cur_prob = detail::LOG_ZERO;
2740 int chosen = 0;
2741 for (int j = 0; j <= u and j <= left_to_distribute; ++j) {
2742 cur_prob = detail::add_log_space(
2743 cur_prob, dp[i - 1][left_to_distribute - j]);
2744 if (random < cur_prob) {
2745 chosen = j;
2746 break;
2747 }
2748 }
2749
2750 part[k - i] = chosen;
2751 left_to_distribute -= chosen;
2752 }
2753 }
2754
2755 for (int &i : part)
2756 i += part_left;
2757 return part;
2758}
2759
2760}; // namespace math
2761
2762/**************
2763 * *
2764 * STRING *
2765 * *
2766 **************/
2767
2768namespace detail {
2769
2770/*
2771 * Regex.
2772 *
2773 * Compatible with testlib's regex.
2774 *
2775 * Operations:
2776 * - A single character yields itself ("a", "3").
2777 * - A list of characters inside square braces yields any a random element
2778 * from the list ("[abc123]").
2779 * - A range of characters is equivalent to listing them ("[a-z1-9A-Z]").
2780 * - A pattern followed by {n} yields the pattern repeated n times ("a{3}").
2781 * - A pattern followed by {l,r} yields the pattern repeated between l and r
2782 * times, uniformly at random ("a{3,5}").
2783 * - A list of patterns separated by | yields a random pattern from the
2784 * list, uniformly at random ("abc|def|ghi").
2785 * - Parentheses can be used for grouping ("a((a|b){3})").
2786 *
2787 * Examples:
2788 * 1. str("[1-9][0-9]{1,2}") generates two- or three-digit numbers.
2789 * 2. str("a[b-d]{2}|e") generates "e" or a random string of length 3, with
2790 * the first character being 'a' and the second and
2791 * third characters being 'b', 'c', or 'd'.
2792 * 3. str("[1-9][0-9]{%d}", n-1) generates n-digit numbers.
2793 *
2794 * Operations defined by {n} and {l,r} are applied from left to right, and
2795 * the pattern that comes before has its delimiters defined either by () or
2796 * [] at its end or is taken from the beginning of the pattern (in
2797 * "a[bc]{2}", "{2}" is applied to "[bc]", and in "[01]abc{3}", the "{3}" is
2798 * appied to "[01]abc").
2799 */
2800
2801// If it has children, it is either a SEQ or an OR group, defined by the
2802// pattern_ field.
2803struct regex_node {
2804 // Considered to be repetition of left_bound != -1, pattern if
2805 // children_.empty(), otherwise "SEQ" or "OR", defined by the pattern_
2806 // field.
2807 std::string
2808 pattern_; // Either pattern, or "SEQ" or "OR" (if !children_.empty()).
2809 std::vector<regex_node> children_; // Children, when SEQ or OR.
2810 int left_bound_, right_bound_; // Left and right bounds of the repetition,
2811 // or -1 if not a repetition.
2812 double
2813 log_space_num_ways_; // Log space number of ways to match the pattern.
2814 std::optional<distinct_container<char>>
2815 distinct_; // Distinct generator for the pattern, for [chars].
2816
2817 // c or [chars].
2818 regex_node(const std::string &pattern)
2819 : pattern_(pattern), left_bound_(-1), right_bound_(-1) {
2820 if (pattern.size() == 1) {
2821 log_space_num_ways_ = math::detail::LOG_ONE;
2822 return;
2823 }
2824 tgen_ensure_against_bug(pattern[0] == '[' and pattern.back() == ']',
2825 "str: invalid regex: expected character class");
2826 int size = pattern.size() - 2;
2827 log_space_num_ways_ = math::detail::log_space(size);
2828 distinct_ = distinct_container<char>(pattern.substr(1, size));
2829 }
2830 // SEQ or OR.
2831 regex_node(const std::string &pattern, std::vector<regex_node> &children)
2832 : pattern_(pattern), left_bound_(-1), right_bound_(-1) {
2833 if (pattern == "SEQ") {
2834 // Multiply the number of ways.
2835 log_space_num_ways_ = math::detail::LOG_ONE;
2836 for (const auto &child : children)
2837 log_space_num_ways_ += child.log_space_num_ways_;
2838 } else if (pattern == "OR") {
2839 // Add the number of ways.
2840 log_space_num_ways_ = math::detail::LOG_ZERO;
2841 for (const auto &child : children)
2842 log_space_num_ways_ = math::detail::add_log_space(
2843 log_space_num_ways_, child.log_space_num_ways_);
2844 } else
2845 tgen_ensure_against_bug("str: invalid regex: expected SEQ or OR");
2846
2847 children_ = std::move(children);
2848 children.clear();
2849 }
2850 // REP.
2851 regex_node(int left_bound, int right_bound, regex_node &child)
2852 : pattern_("REP"), left_bound_(left_bound), right_bound_(right_bound) {
2853 log_space_num_ways_ = math::detail::LOG_ZERO;
2854 for (int i = left_bound; i <= right_bound; ++i)
2855 log_space_num_ways_ = math::detail::add_log_space(
2856 log_space_num_ways_, i * child.log_space_num_ways_);
2857
2858 children_.push_back(std::move(child));
2859 }
2860};
2861
2862// State of the regex parser.
2863struct regex_state {
2864 std::vector<regex_node> cur; // Current sequence of nodes.
2865 std::vector<regex_node> branches; // Branches of the current OR group.
2866};
2867
2868// Creates a SEQ node from the current state.
2869inline regex_node make_regex_seq(regex_state &st) {
2870 return regex_node("SEQ", st.cur);
2871}
2872
2873// Finishes current state.
2874inline regex_node finish_regex_state(regex_state &st) {
2875 // SEQ.
2876 if (st.branches.empty())
2877 return make_regex_seq(st);
2878
2879 // OR.
2880 st.branches.push_back(make_regex_seq(st));
2881 return regex_node("OR", st.branches);
2882}
2883
2884// Parses a regex pattern into a tree, computing the number of ways to match the
2885// pattern.
2886inline regex_node parse_regex(std::string regex) {
2887 std::string new_regex;
2888 for (char c : regex)
2889 if (c != ' ')
2890 new_regex += c;
2891 swap(regex, new_regex);
2892 regex_state cur;
2893 std::vector<regex_state> stack;
2894
2895 for (size_t i = 0; i < regex.size(); ++i) {
2896 char c = regex[i];
2897
2898 if (c == '(') {
2899 // Pushes the current state to the stack.
2900 stack.push_back(std::move(cur));
2901 cur = regex_state();
2902 } else if (c == ')') {
2903 // Finishes the current state, and adds it to the parent.
2904 regex_node node = finish_regex_state(cur);
2905
2906 tgen_ensure(!stack.empty(), "str: invalid regex: unmatched `)`");
2907 cur = std::move(stack.back());
2908 stack.pop_back();
2909
2910 cur.cur.push_back(std::move(node));
2911 } else if (c == '|') {
2912 // Starts a new OR group.
2913 regex_node node = make_regex_seq(cur);
2914 cur.branches.push_back(std::move(node));
2915 } else if (c == '[') {
2916 // Parses a character class.
2917 std::string chars;
2918
2919 for (++i; i < regex.size() and regex[i] != ']'; ++i) {
2920 if (i + 2 < regex.size() and regex[i + 1] == '-') {
2921 char a = regex[i], b = regex[i + 2];
2922 if (a > b)
2923 std::swap(a, b);
2924 for (char x = a; x <= b; ++x)
2925 chars += x;
2926 i += 2;
2927 } else
2928 chars += regex[i];
2929 }
2930
2931 tgen_ensure(i < regex.size() and regex[i] == ']',
2932 "str: invalid regex: unmatched `[`");
2933 cur.cur.emplace_back("[" + chars + "]");
2934 } else if (c == '{') {
2935 // Parses a repetition.
2936 ++i;
2937 int l = -1, r = -1;
2938
2939 while (i < regex.size() and
2940 isdigit(static_cast<unsigned char>(regex[i]))) {
2941 if (l == -1)
2942 l = 0;
2943 tgen_ensure(l <= static_cast<int>(1e8),
2944 "str: invalid regex: number too large inside `{}`");
2945 l = 10 * l + (regex[i] - '0');
2946 ++i;
2947 }
2948
2949 if (i < regex.size() and regex[i] == ',') {
2950 ++i;
2951 while (i < regex.size() and
2952 isdigit(static_cast<unsigned char>(regex[i]))) {
2953 if (r == -1)
2954 r = 0;
2956 r <= static_cast<int>(1e8),
2957 "str: invalid regex: number too large inside `{}`");
2958 r = 10 * r + (regex[i] - '0');
2959 ++i;
2960 }
2961 } else
2962 r = l;
2963
2964 tgen_ensure(i < regex.size() and regex[i] == '}',
2965 "str: invalid regex: unmatched `{`");
2966 tgen_ensure(l != -1 and r != -1,
2967 "str: invalid regex: missing number inside `{}`");
2968 tgen_ensure(l <= r, "invalid regex: invalid range inside `{}`");
2969
2970 // Creates a REP node from the previous node.
2971 tgen_ensure(!cur.cur.empty(),
2972 "str: invalid regex: expected expression before `{}`");
2973
2974 regex_node rep(l, r, cur.cur.back());
2975 cur.cur.pop_back();
2976 cur.cur.push_back(std::move(rep));
2977 } else {
2978 // Creates a char node.
2979 cur.cur.emplace_back(std::string(1, c));
2980 }
2981 }
2982
2983 tgen_ensure(stack.empty(), "str: invalid regex: unmatched `(`");
2984 return finish_regex_state(cur);
2985}
2986
2987// Generates a uniformly random string that matches the given regex.
2988inline void gen_regex(const regex_node &node, std::string &str) {
2989 // For [chars], generate a random character from the list.
2990 if (node.pattern_[0] == '[') {
2991 str += node.pattern_[1 + next<int>(0, node.pattern_.size() - 3)];
2992 return;
2993 }
2994
2995 // For REP, generate a random number of times to repeat the pattern.
2996 if (node.left_bound_ != -1) {
2997 // Generates a random value W from 0 to num_ways.
2998 // log(W) = log(random(0, 1) * num_ways)
2999 // = log(random(0, 1)) + log(num_ways).
3000 double log_rand = math::detail::log_space(next<double>(0, 1)) +
3001 node.log_space_num_ways_;
3002 double cur_prob = math::detail::LOG_ZERO;
3003 double child_num_ways = node.children_[0].log_space_num_ways_;
3004
3005 for (int i = node.left_bound_; i <= node.right_bound_; ++i) {
3006 cur_prob =
3007 math::detail::add_log_space(cur_prob, i * child_num_ways);
3008 if (log_rand <= cur_prob) {
3009 for (int j = 0; j < i; ++j)
3010 gen_regex(node.children_[0], str);
3011 return;
3012 }
3013 }
3014
3015 tgen_ensure_against_bug(false,
3016 "str: log_rand > cur_prob in REP gen_regex");
3017 }
3018
3019 // For SEQ, generate all children.
3020 if (!node.children_.empty() and node.pattern_ == "SEQ") {
3021 for (const regex_node &child : node.children_)
3022 gen_regex(child, str);
3023 return;
3024 }
3025
3026 // For OR, generate a random child.
3027 if (!node.children_.empty() and node.pattern_ == "OR") {
3028 // Generates a random value W from 0 to num_ways.
3029 // log(W) = log(random(0, 1) * num_ways)
3030 // = log(random(0, 1)) + log(num_ways).
3031 double log_rand = math::detail::log_space(next<double>(0, 1)) +
3032 node.log_space_num_ways_;
3033 double cur_prob = math::detail::LOG_ZERO;
3034
3035 for (const regex_node &child : node.children_) {
3036 cur_prob = math::detail::add_log_space(cur_prob,
3037 child.log_space_num_ways_);
3038 if (log_rand <= cur_prob) {
3039 gen_regex(child, str);
3040 return;
3041 }
3042 }
3043
3044 tgen_ensure_against_bug(false,
3045 "str: log_rand > cur_prob in OR gen_regex");
3046 }
3047
3048 // For char, generate the character.
3049 detail::tgen_ensure_against_bug(
3050 node.pattern_.size() == 1,
3051 "str: invalid regex: expected single character, but got `" +
3052 node.pattern_ + "`");
3053 str += node.pattern_[0];
3054}
3055
3056// Formats a regex string with given arguments.
3057template <typename... Args>
3058std::string regex_format(const std::string &s, Args &&...args) {
3059 if constexpr (sizeof...(Args) == 0) {
3060 return s;
3061 } else {
3062 int size = std::snprintf(nullptr, 0, s.c_str(), args...) + 1;
3063 std::string buf(size, '\0');
3064 std::snprintf(buf.data(), size, s.c_str(), args...);
3065 buf.pop_back(); // remove '\0'
3066 return buf;
3067 }
3068}
3069
3070} // namespace detail
3071
3072/*
3073 * String generator.
3074 */
3075
3076struct str : gen_base<str> {
3077 std::optional<list<char>> list_; // List of characters.
3078 std::optional<detail::regex_node>
3079 root_; // Root node of the regex tree for the whole string.
3080
3081 // Creates generator for strings of size 'size', with random characters in
3082 // [value_left, value_right].
3083 str(int size, char value_left = 'a', char value_right = 'z')
3084 : list_(list<char>(size, value_left, value_right)) {}
3085
3086 // Creates generator for strings of size 'size', with random characters in
3087 // 'chars'.
3088 str(int size, std::set<char> chars) : list_(list<char>(size, chars)) {}
3089
3090 // Creates generator for strings that match the given regex.
3091 template <typename... Args> str(const std::string &regex, Args &&...args) {
3092 tgen_ensure(regex.size() > 0, "str: regex must be non-empty");
3093
3094 root_ = detail::parse_regex(
3095 detail::regex_format(regex, std::forward<Args>(args)...));
3096 }
3097
3098 // Restricts strings for str[idx] = value.
3099 str &fix(int idx, char character) {
3100 tgen_ensure(!root_, "str: cannot add restriction for regex");
3101 list_->fix(idx, character);
3102 return *this;
3103 }
3104
3105 // Restricts strings for list[S] to be equal, for given subset S of indices.
3106 str &equal(std::set<int> indices) {
3107 tgen_ensure(!root_, "str: cannot add restriction for regex");
3108 list_->equal(indices);
3109 return *this;
3110 }
3111
3112 // Restricts strings for str[idx_1] = str[idx_2].
3113 str &equal(int idx_1, int idx_2) {
3114 tgen_ensure(!root_, "str: cannot add restriction for regex");
3115 list_->equal(idx_1, idx_2);
3116 return *this;
3117 }
3118
3119 // Restricts strings for str[left..right] to have all equal values.
3120 str &equal_range(int left, int right) {
3121 tgen_ensure(!root_, "str: cannot add restriction for regex");
3122 list_->equal_range(left, right);
3123 return *this;
3124 }
3125
3126 // Restricts strings for all equal chars.
3128 tgen_ensure(!root_, "str: cannot add restriction for regex");
3129 list_->all_equal();
3130 return *this;
3131 }
3132
3133 // Restricts strings for str[left..right] to be a palindrome.
3134 str &palindrome(int left, int right) {
3135 tgen_ensure(!root_, "str: cannot add restriction for regex");
3136 tgen_ensure(0 <= left and left <= right and right < list_->size_,
3137 "str: range indices must be valid");
3138 for (int i = left; i < right - (i - left); ++i)
3139 equal(i, right - (i - left));
3140 return *this;
3141 }
3142
3143 // Restricts strings for the entire string to be a palindrome.
3145 tgen_ensure(!root_, "str: cannot add restriction for regex");
3146 return palindrome(0, list_->size_ - 1);
3147 }
3148
3149 // Restricts strings for str[S] to be different (distinct), for given subset
3150 // S of indices.
3151 str &different(std::set<int> indices) {
3152 tgen_ensure(!root_, "str: cannot add restriction for regex");
3153 list_->different(indices);
3154 return *this;
3155 }
3156
3157 // Restricts strings for str[idx_1] != str[idx_2].
3158 str &different(int idx_1, int idx_2) {
3159 tgen_ensure(!root_, "str: cannot add restriction for regex");
3160 list_->different(idx_1, idx_2);
3161 return *this;
3162 }
3163
3164 // Restricts lists for list[left..right] to have all different chars.
3165 str &different_range(int left, int right) {
3166 tgen_ensure(!root_, "str: cannot add restriction for regex");
3167 list_->different_range(left, right);
3168 return *this;
3169 }
3170
3171 // Restricts strings for all chars to be different.
3173 tgen_ensure(!root_, "str: cannot add restriction for regex");
3174 list_->all_different();
3175 return *this;
3176 }
3177
3178 // str value.
3180 using tgen_is_sequential_tag = detail::is_sequential_tag;
3181 using tgen_has_subset_defined_tag = detail::has_subset_defined_tag;
3182
3183 using value_type = char;
3184 using std_type = std::string;
3185 std::string str_;
3186
3187 value(const std::string &str) : str_(str) {
3188 tgen_ensure(!str_.empty(), "str: value: cannot be empty");
3189 }
3190
3191 // Fetches size.
3192 int size() const { return str_.size(); }
3193
3194 // Fetches position idx.
3195 char &operator[](int idx) {
3196 tgen_ensure(0 <= idx and idx < size(),
3197 "str: instane: index out of bounds");
3198 return str_[idx];
3199 }
3200 const char &operator[](int idx) const {
3201 tgen_ensure(0 <= idx and idx < size(),
3202 "str: value: index out of bounds");
3203 return str_[idx];
3204 }
3205
3206 // Sorts characters in non-decreasing order.
3207 // O(n log n).
3209 std::sort(str_.begin(), str_.end());
3210 return *this;
3211 }
3212
3213 // Reverses string.
3214 // O(n).
3216 std::reverse(str_.begin(), str_.end());
3217 return *this;
3218 }
3219
3220 // Lowercases all characters.
3221 // O(n).
3223 for (char &c : str_)
3224 c = std::tolower(c);
3225 return *this;
3226 }
3227
3228 // Uppercases all characters.
3229 // O(n).
3231 for (char &c : str_)
3232 c = std::toupper(c);
3233 return *this;
3234 }
3235
3236 // Concatenates two values.
3237 // Linear.
3238 value operator+(const value &rhs) { return value(str_ + rhs.str_); }
3239
3240 // Prints to std::ostream.
3241 friend std::ostream &operator<<(std::ostream &out, const value &inst) {
3242 return out << inst.str_;
3243 }
3244
3245 // Gets a std::string representing the value.
3246 std::string to_std() const { return str_; }
3247 };
3248
3249 // Generates str value.
3250 // If created from restrictions: O(n log n).
3251 // If created from regex: expected linear.
3252 value gen() const {
3253 if (root_) {
3254 // Regex.
3255 std::string ret_str;
3256 gen_regex(*root_, ret_str);
3257 return value(ret_str);
3258 } else {
3259 // List.
3260 std::vector<char> vec = list_->gen().to_std();
3261 return value(std::string(vec.begin(), vec.end()));
3262 }
3263 }
3264};
3265
3266/************
3267 * *
3268 * PAIR *
3269 * *
3270 ************/
3271
3272namespace detail {
3273
3274// Generates pair first == second.
3275// O(1).
3276template <typename T> std::pair<T, T> gen_eq(T L1, T R1, T L2, T R2) {
3277 T L = std::max(L1, L2);
3278 T R = std::min(R1, R2);
3279
3280 tgen_ensure(L <= R, "pair: no valid values to generate");
3281 T x = next<T>(L, R);
3282 return {x, x};
3283}
3284
3285// Returns {R1-L1+1, R2-L2+1}.
3286template <typename T>
3287std::pair<u128, u128> get_n_and_m(T L1, T R1, T L2, T R2) {
3288 u128 n = static_cast<i128>(R1) - L1 + 1;
3289 u128 m = static_cast<i128>(R2) - L2 + 1;
3290 return {n, m};
3291}
3292
3293// Returns first + first+1 + ... + last,
3294// num_term terms. Avoids overflow.
3295static u128 pos_arith_sum(u128 first, u128 last, u128 num_terms) {
3296 u128 x = first + last, y = num_terms;
3297
3298 // x * y / 2, avoiding overflow.
3299 if (x % 2 == 0)
3300 x /= 2;
3301 else
3302 y /= 2;
3303
3304 return x * y;
3305}
3306
3307// Generates pair first != second.
3308// O(1) expected.
3309template <typename T> std::pair<T, T> gen_neq(T L1, T R1, T L2, T R2) {
3310 auto [n, m] = get_n_and_m(L1, R1, L2, R2);
3311
3312 T L_intersect = std::max(L1, L2);
3313 T R_intersect = std::min(R1, R2);
3314 u128 inter = static_cast<i128>(R_intersect) - L_intersect + 1;
3315
3316 u128 total = n * m - inter;
3317 tgen_ensure(total > 0, "pair: no valid values to generate");
3318
3319 // Runs O(1) expected times in the worst case.
3320 T a, b;
3321 do {
3322 a = next<T>(L1, R1);
3323 b = next<T>(L2, R2);
3324 } while (a == b);
3325
3326 return {a, b};
3327}
3328
3329// For lt, splits 'second' into two regions:
3330// 1) second <= R1 -> number of 'first' is (second - L1)
3331// 2) second > R1 -> number of 'first' is (R1 - L1 + 1)
3332// Returns {count_region1, count_region2}.
3333// O(1).
3334template <typename T>
3335std::pair<u128, u128> count_lt_regions(T L1, T R1, T L2, T R2) {
3336 auto [n, m] = get_n_and_m(L1, R1, L2, R2);
3337
3338 // 'second' must be >= L1 + 1.
3339 i128 L_second = std::max<i128>(L2, static_cast<i128>(L1) + 1);
3340 i128 R_second = R2;
3341
3342 // Split point for 'second'.
3343 i128 split = std::min<i128>(R_second, R1);
3344
3345 // Region 1: b in [L_second, split].
3346 u128 len1 = std::max<i128>(0, split - L_second + 1);
3347
3348 u128 count_region1 = 0;
3349 if (len1 > 0) {
3350 // For b in [L_second, split], there are (b - L1) ways.
3351 i128 first = L_second - L1;
3352 i128 last = split - L1;
3353
3354 // Arithmetic series first + (first + 1) + ... + last, len1 terms.
3355 count_region1 = pos_arith_sum(first, last, len1);
3356 }
3357
3358 // Region 2: b > R1.
3359 // For b in [R1+1, R_second], there are 'n' ways.
3360 i128 L_second_region2 = std::max(L_second, static_cast<i128>(R1) + 1);
3361
3362 u128 len2 = std::max<i128>(0, R_second - L_second_region2 + 1);
3363 u128 count_region2 = len2 * n;
3364
3365 return {count_region1, count_region2};
3366}
3367
3368// Generates pair first < second.
3369// O(log(R1 - L1 + 1) + log(R2 - L2 + 1)).
3370template <typename T> std::pair<T, T> gen_lt(T L1, T R1, T L2, T R2) {
3371 auto [n, m] = get_n_and_m(L1, R1, L2, R2);
3372
3373 // 'second' needs to be at least L1 + 1 to have a valid value for
3374 // 'first'.
3375 i128 L_second = std::max<i128>(L2, static_cast<i128>(L1) + 1);
3376 i128 R_second = R2;
3377
3378 // Splits 'second' into two regions:
3379 // 1) b <= R1 -> number of 'first' is (b - L1);
3380 // 2) b > R1 -> number of 'first' is (R1 - L1 + 1).
3381 i128 split = std::min<i128>(R_second, R1);
3382
3383 auto [count_region1, count_region2] = count_lt_regions(L1, R1, L2, R2);
3384 u128 total = count_region1 + count_region2;
3385 tgen_ensure(total > 0, "pair: no valid values to generate");
3386
3387 u128 k = detail::next128(total);
3388 if (k < count_region1) {
3389 // Region 1: invert arithmetic series.
3390
3391 // For b in [L_second, split].
3392 u128 len1 = std::max<i128>(0, split - L_second + 1);
3393
3394 // We consider b in [L_second, L_second + d].
3395 // Each b contributes (b - L1) = base + (b - L_second).
3396 // So we sum: base + (base+1) + ... + (base+d)
3397 // d in [0, len1).
3398
3399 i128 base = L_second - L1;
3400 i128 lo = 0, hi = static_cast<i128>(len1) - 1;
3401
3402 while (lo < hi) {
3403 i128 mid = lo + (hi - lo) / 2;
3404
3405 if (pos_arith_sum(base, base + mid, mid + 1) <= k)
3406 lo = mid + 1;
3407 else
3408 hi = mid;
3409 }
3410 i128 d = lo;
3411
3412 // Subtracts prefix sum with d-1 terms from k.
3413 if (d > 0)
3414 k -= pos_arith_sum(base, base + d - 1, d);
3415
3416 return {L1 + static_cast<T>(k), L_second + d};
3417 } else {
3418 // Region 2: uniform block of size n.
3419 k -= count_region1;
3420
3421 // For b in [R1+1, R_second], there are 'n' ways.
3422 i128 L_second_region2 = std::max(L_second, static_cast<i128>(R1) + 1);
3423
3424 return {L1 + static_cast<T>(k % n),
3425 L_second_region2 + static_cast<T>(k / n)};
3426 }
3427}
3428
3429// Generates pair first > second.
3430// O(log(R1 - L1 + 1) + log(R2 - L2 + 1)).
3431template <typename T> std::pair<T, T> gen_gt(T L1, T R1, T L2, T R2) {
3432 auto [first, second] = gen_lt(L2, R2, L1, R1);
3433 return {second, first};
3434}
3435
3436// Generates pair first <= second.
3437// O(log(R1 - L1 + 1) + log(R2 - L2 + 1)).
3438template <typename T> std::pair<T, T> gen_leq(T L1, T R1, T L2, T R2) {
3439 // Counts how many pairs are there with first = second.
3440 i128 L_intersect = std::max(L1, L2);
3441 i128 R_intersect = std::min(R1, R2);
3442 u128 eq_count = std::max<i128>(0, R_intersect - L_intersect + 1);
3443
3444 // Counts how many pairs are there with first < second.
3445 auto [lt_region1, lt_region2] = count_lt_regions(L1, R1, L2, R2);
3446 u128 lt_count = lt_region1 + lt_region2;
3447
3448 u128 total = eq_count + lt_count;
3449 tgen_ensure(total > 0, "pair: no valid values to generate");
3450
3451 if (detail::next128(total) < eq_count)
3452 return gen_eq(L1, R1, L2, R2);
3453 return gen_lt(L1, R1, L2, R2);
3454}
3455
3456// Generates pair first >= second.
3457// O(log(R1 - L1 + 1) + log(R2 - L2 + 1)).
3458template <typename T> std::pair<T, T> gen_geq(T L1, T R1, T L2, T R2) {
3459 auto [first, second] = gen_leq(L2, R2, L1, R1);
3460 return {second, first};
3461}
3462
3463}; // namespace detail
3464
3465/*
3466 * Pair generator.
3467 *
3468 * Pairs of integral types.
3469 */
3470
3471template <typename T> struct pair : gen_base<pair<T>> {
3472 std::pair<T, T> first_, second_; // Range of first and second values.
3473 // Type of restriction.
3474 enum class restriction_type { eq, neq, lt, gt, leq, geq, unspecified };
3475 restriction_type type_ = restriction_type::unspecified;
3476
3477 // Creates a pair with random values in [first_l, first_r] and [second_l,
3478 // second_r].
3479 pair(T first_left, T first_right, T second_left, T second_right)
3480 : first_(first_left, first_right), second_(second_left, second_right) {
3481 tgen_ensure(first_left <= first_right,
3482 "pair: first range must be valid");
3483 tgen_ensure(second_left <= second_right,
3484 "pair: second range must be valid");
3485 }
3486
3487 // Creates a pair with random values in [both_l, both_r].
3488 pair(T both_left, T both_right)
3489 : pair(both_left, both_right, both_left, both_right) {}
3490
3491 // Restricts pair for first = second.
3493 type_ = restriction_type::eq;
3494 return *this;
3495 }
3496
3497 // Restricts pair for first != second.
3499 type_ = restriction_type::neq;
3500 return *this;
3501 }
3502
3503 // Restricts pair for first < second.
3505 type_ = restriction_type::lt;
3506 return *this;
3507 }
3508
3509 // Restricts pair for first > second.
3511 type_ = restriction_type::gt;
3512 return *this;
3513 }
3514
3515 // Restricts pair for first <= second.
3517 type_ = restriction_type::leq;
3518 return *this;
3519 }
3520
3521 // Restricts pair for first >= second.
3523 type_ = restriction_type::geq;
3524 return *this;
3525 }
3526
3527 // Pair value.
3529 using value_type = T;
3530 using std_type = std::pair<T, T>;
3531
3532 std::pair<T, T> pair_;
3533 char sep_;
3534
3535 value(const std::pair<T, T> &pair) : pair_(pair), sep_(' ') {}
3536 value(const T &first, const T &second)
3537 : pair_(first, second), sep_(' ') {}
3538
3539 T first() const { return pair_.first; }
3540 T second() const { return pair_.second; }
3541
3542 // Sets the separator for the pair, for printing.
3543 value &separator(char sep) {
3544 sep_ = sep;
3545 return *this;
3546 }
3547
3548 // Prints to std::ostream, separated by sep_.
3549 friend std::ostream &operator<<(std::ostream &out, const value &inst) {
3550 return out << inst.pair_.first << inst.sep_ << inst.pair_.second;
3551 }
3552
3553 // Gets a std::pair representing the value.
3554 auto to_std() const {
3555 if constexpr (!is_generator_value<T>::value) {
3556 return pair_;
3557 } else {
3558 std::pair<typename T::std_type, typename T::std_type> pair(
3559 pair_.first.to_std(), pair_.second.to_std());
3560 return pair;
3561 }
3562 }
3563 };
3564
3565 // Generates a random pair.
3566 // O(log(R1 - L1 + 1) + log(R2 - L2 + 1)).
3567 value gen() const {
3568 T L1 = first_.first, R1 = first_.second;
3569 T L2 = second_.first, R2 = second_.second;
3570
3571 switch (type_) {
3572 case restriction_type::unspecified:
3573 return {next<T>(L1, R1), next<T>(L2, R2)};
3574 case restriction_type::eq:
3575 return detail::gen_eq<T>(L1, R1, L2, R2);
3576 case restriction_type::neq:
3577 return detail::gen_neq<T>(L1, R1, L2, R2);
3578 case restriction_type::lt:
3579 return detail::gen_lt<T>(L1, R1, L2, R2);
3580 case restriction_type::gt:
3581 return detail::gen_gt<T>(L1, R1, L2, R2);
3582 case restriction_type::leq:
3583 return detail::gen_leq<T>(L1, R1, L2, R2);
3584 case restriction_type::geq:
3585 return detail::gen_geq<T>(L1, R1, L2, R2);
3586 }
3587 throw detail::error("pair: unknown restriction type");
3588 }
3589};
3590
3591/*************
3592 * *
3593 * GRAPH *
3594 * *
3595 *************/
3596/*
3597 * Graph generation.
3598 *
3599 * Graphs have `n` edges and `m` edges. It has vertices indexed from 0 to n-1.
3600 * These are labeleted graphs, that is, isomorphism is not taken into account.
3601 * VWeight is the type of vertex weights, and EWeight are the type of edge
3602 * weights.
3603 */
3604
3605template <typename VWeight = int, typename EWeight = int>
3606struct graph : gen_base<graph<VWeight, EWeight>> {
3607 int n_, m_; // Number of vertices and edges.
3608 std::set<std::pair<int, int>> edg_; // Edges that were set.
3609 bool is_directed_; // If graph is directed.
3610 bool has_self_loops_; // If self-loops are allowed.
3611
3612 graph(int n, int m, bool is_directed = false, bool has_self_loops = false)
3613 : n_(n), m_(m), is_directed_(is_directed),
3614 has_self_loops_(has_self_loops) {}
3615
3616 graph &add_edge(int u, int v) {
3617 tgen_ensure(0 <= u and u < n_, "vertex index must be valid");
3618 tgen_ensure(0 <= v and v < n_, "vertex index must be valid");
3619
3620 if (!is_directed_ and u > v)
3621 std::swap(u, v);
3622 edg_.emplace(u, v);
3623 return *this;
3624 }
3625
3626 // A graph::value
3628 int n_, m_; // Number of vertices and edges.
3629 std::vector<std::set<int>> adj_; // Adjacency list.
3630 bool add_1_; // If should add 1 for printing vertex ids.
3631 bool print_nm_; // If should print n and m.
3632 bool shuffle_; // If should shuffle output when printing.
3633
3634 // Create value from edge n, m, and edge list. The edges are
3635 // considered to be directed.
3636 value(int n, int m, const std::set<std::pair<int, int>> &edges = {})
3637 : n_(n), m_(m), adj_(n_), add_1_(false), print_nm_(false),
3638 shuffle_(false) {
3639 for (auto [u, v] : edges) {
3640 tgen_ensure(0 <= u and u < n, "graph: value: invalid edge");
3641 tgen_ensure(0 <= v and v < n, "graph: value: invalid edge");
3642 adj_[u].insert(v);
3643 }
3644 }
3645
3646 int n() const { return n_; }
3647
3648 int m() const { return m_; }
3649
3650 const std::vector<std::set<int>> &adj() const { return adj_; }
3651
3652 value &add_1() {
3653 add_1_ = true;
3654 return *this;
3655 }
3656
3657 value &shuffle() {
3658 shuffle_ = true;
3659 return *this;
3660 }
3661
3662 value &print_nm() {
3663 print_nm_ = true;
3664 return *this;
3665 }
3666
3667 // Prints to std::ostream.
3668 friend std::ostream &operator<<(std::ostream &out, const value &inst) {
3669 if (inst.print_nm_)
3670 out << inst.n() << " " << inst.m() << std::endl;
3671
3672 std::vector<int> print_label(inst.n());
3673 std::iota(print_label.begin(), print_label.end(), 0);
3674 if (inst.shuffle_)
3675 tgen::shuffle(print_label.begin(), print_label.end());
3676
3677 std::vector<std::pair<int, int>> edges;
3678 for (int u = 0; u < inst.n(); ++u)
3679 for (int v : inst.adj()[u])
3680 edges.emplace_back(u, v);
3681 if (inst.shuffle_)
3682 tgen::shuffle(edges.begin(), edges.end());
3683
3684 detail::tgen_ensure_against_bug(edges.size() == inst.m(),
3685 "graph: invalid number of edges");
3686
3687 for (auto [u, v] : edges)
3688 out << (print_label[u] + inst.add_1_) << " "
3689 << (print_label[v] + inst.add_1_) << std::endl;
3690 ;
3691
3692 return out;
3693 }
3694
3695 std::tuple<int, int, std::vector<std::set<int>>> to_std() {
3696 return std::tuple(n_, m_, adj_);
3697 }
3698 };
3699
3700 value gen() {
3701 tgen::pair gen_repeat(0, n_ - 1);
3702 if (has_self_loops_) {
3703 if (!is_directed_)
3704 gen_repeat.leq();
3705 } else {
3706 if (is_directed_)
3707 gen_repeat.neq();
3708 else
3709 gen_repeat.lt();
3710 }
3711 auto edge_gen = gen_repeat.distinct();
3712 auto edges = edg_;
3713
3714 tgen_ensure(edges.size() <= m_, "too many edges were added");
3715
3716 while (edges.size() < m_) {
3717 try {
3718 edges.insert(edge_gen.gen().to_std());
3719 } catch (std::runtime_error &e) {
3720 throw detail::error(
3721 std::string("graph: probably enough edges to generate: ") +
3722 e.what());
3723 }
3724 }
3725
3726 return value(n_, m_, edges);
3727 }
3728
3729 static value k(int n) { return graph(n, n * (n - 1) / 2).gen(); }
3730};
3731
3732/************
3733 * *
3734 * HACK *
3735 * *
3736 ************/
3737
3738namespace hack {
3739
3740namespace detail {
3741
3742using namespace tgen::detail;
3743
3744// Computes polynomial hash of a string.
3745// O(|s|).
3746inline int hash_string(const std::string &s, int base, int mod) {
3747 long long h = 0;
3748 for (char c : s)
3749 h = (h * base + c - 'a' + 1) % mod;
3750 return h;
3751}
3752
3753// Estimates the length of the string to very likely have a collision.
3754inline int estimate_length(int alphabet_size, int mod) {
3755 // Magic constants.
3756 double base_len = 2.5 * std::log(std::sqrt(static_cast<double>(mod)));
3757 double scale = std::log(static_cast<double>(alphabet_size)) / std::log(2.0);
3758 double adjusted = base_len / std::max(1.0, scale * 0.7);
3759
3760 return static_cast<int>(std::ceil(adjusted));
3761}
3762
3763// Collides two strings to have the same polynomial hash.
3764// O(sqrt(mod) log(mod)) with high probability.
3765inline std::pair<std::string, std::string>
3766birthday_attack(const std::vector<std::string> &alphabet, int base, int mod) {
3767 tgen_ensure(0 < base and base < mod,
3768 "birthday_attack: base must be in (0, mod)");
3769 std::map<uint64_t, std::vector<int>> seen;
3770 int length = estimate_length(alphabet.size(), mod);
3771
3772 while (true) {
3773 std::vector<int> seq(length);
3774
3775 std::string s;
3776 s.reserve(length * alphabet[0].size());
3777
3778 for (int i = 0; i < length; ++i) {
3779 seq[i] = next<int>(0, alphabet.size() - 1);
3780 s += alphabet[seq[i]];
3781 }
3782
3783 int h = hash_string(s, base, mod);
3784
3785 auto it = seen.find(h);
3786 if (it != seen.end() and it->second != seq) {
3787 std::string a, b;
3788
3789 for (int x : it->second)
3790 a += alphabet[x];
3791 for (int x : seq)
3792 b += alphabet[x];
3793
3794 if (a != b)
3795 return {a, b};
3796 }
3797
3798 seen[h] = seq;
3799 }
3800}
3801
3802// Tried to find correct multipliers for unordered_map/set to force
3803// collisions. O(1).
3804inline std::set<long long> std_hash_multipliers() {
3805 std::set<long long> multipliers = {85229};
3806
3807 // Codeforces GCC GNU G++17 7.3.0 case.
3808 bool codeforces_gcc_case = true;
3809 if (cpp.version_ != 0 and cpp.version_ != 17)
3810 codeforces_gcc_case = false;
3811 if (compiler.kind_ != compiler_kind::unknown and
3812 compiler.kind_ != compiler_kind::gcc)
3813 codeforces_gcc_case = false;
3814 if (compiler.major_ > 7)
3815 codeforces_gcc_case = false;
3816
3817 if (codeforces_gcc_case)
3818 multipliers.insert(107897);
3819
3820 return multipliers;
3821}
3822
3823} // namespace detail
3824
3825// Fetches prefix of length n of the string "abacabadabacabae...".
3826// O(n).
3827inline std::string abacaba(int n) {
3828 tgen_ensure(n > 0, "str: size must be positive");
3829 std::string str = "a";
3830 char c = 'a';
3831 while (static_cast<int>(str.size()) < n) {
3832 int prev_size = str.size();
3833 str += ++c;
3834 for (int j = 0; j < prev_size and static_cast<int>(str.size()) < n; ++j)
3835 str += str[j];
3836 }
3837 return str;
3838}
3839
3840// Two strings that have same polynomial hash for any base, for
3841// mod = power of 2 up to 2^64.
3842// Thue–Morse.
3843// O(1).
3844inline std::pair<std::string, std::string> unsigned_polynomial_hash_hack() {
3845 std::string a, b;
3846 int size = 1 << 10;
3847 for (int i = 0; i < size; ++i) {
3848 a += 'a' + math::detail::popcount(i) % 2;
3849 b += 'a' + ('b' - a[i]);
3850 }
3851 return {a, b};
3852}
3853
3854// Collides two strings to have the same polynomial hash.
3855// O(sqrt(mod) log(mod)) with high probability.
3856// 0 < base < mod.
3857inline std::pair<std::string, std::string>
3858polynomial_hash_hack(int alphabet_size, int base, int mod) {
3859 tgen_ensure(alphabet_size > 1, "str: alphabet size must be greater than 1");
3860 tgen_ensure(0 < base and base < mod, "str: base must be in (0, mod)");
3861
3862 std::vector<std::string> alphabet(alphabet_size);
3863 for (int i = 0; i < alphabet_size; ++i)
3864 alphabet[i] = std::string(1, 'a' + i);
3865 std::iota(alphabet.begin(), alphabet.end(), 'a');
3866 return detail::birthday_attack(alphabet, base, mod);
3867}
3868
3869// Collides two strings to have the same polynomial hash for multiple bases
3870// and mods (up to 2 pairs).
3871// O(sqrt(mod) log^2 (mod)) with high probability,
3872// with mod = max(mod_1, mod_2).
3873inline std::pair<std::string, std::string>
3874polynomial_hash_hack(int alphabet_size, std::vector<int> bases,
3875 std::vector<int> mods) {
3876 tgen_ensure(bases.size() == mods.size(),
3877 "str: bases and mods must have the same size");
3878 tgen_ensure(bases.size() > 0,
3879 "str: must have at least one (base, mod) pair");
3880 tgen_ensure(bases.size() <= 2, "str: multi-hash hack only supported "
3881 "for up to 2 (base, mod) pairs");
3882
3883 std::vector<std::string> alphabet(alphabet_size);
3884 for (int i = 0; i < alphabet_size; ++i)
3885 alphabet[i] = std::string(1, 'a' + i);
3886 auto [S1, T1] = detail::birthday_attack(alphabet, bases[0], mods[0]);
3887 if (bases.size() == 1)
3888 return {S1, T1};
3889 return detail::birthday_attack({S1, T1}, bases[1], mods[1]);
3890}
3891
3892// Returns a list of integers for unordered_map/set to force collisions.
3893// O(size).
3894inline std::vector<long long> std_unordered(int size) {
3895 tgen_ensure(size > 0, "misc: unordered_hack: size must be positive");
3896 std::set<long long> multipliers = detail::std_hash_multipliers();
3897 long long mult = 1;
3898 std::set<long long>::iterator it = multipliers.begin();
3899
3900 std::vector<long long> list;
3901 while (static_cast<int>(list.size()) < size) {
3902 list.push_back(mult * (*it));
3903 ++it;
3904 if (it == multipliers.end()) {
3905 it = multipliers.begin();
3906 ++mult;
3907 }
3908 }
3909 return list;
3910}
3911
3912// Returns queries that force \Omega(n sqrt n) time
3913// for Mo algorithm for offline range queries.
3914// This forces the following expected number of pointer moves, assuming standard
3915// implementations:
3916// For block-based Mo with blocks of size b and q >> n/b:
3917// \Theta(n^2 / b + q*b).
3918// For Hilbert-based Mo:
3919// \Theta(q sqrt n).
3920// O(n log n).
3921inline std::vector<std::pair<int, int>> mo(int n, int q) {
3922 std::set<std::pair<int, int>> queries;
3923 for (int i = 0; i < n; ++i) {
3924 queries.emplace(0, i);
3925 queries.emplace(i, i);
3926 queries.emplace(i, n - 1);
3927 }
3928 return distinct_container(queries).gen_list(q).to_std();
3929}
3930
3931// Returns list of strings that have a high cost to insert in a std::set.
3932// Forces cost \Theta(size log(size)).
3933// O(size log(size)).
3934inline std::vector<std::string> string_set(int size) {
3935 std::vector<std::string> list;
3936 int k = 0, left = size;
3937 while (left > 0) {
3938 int cur_size = std::min(left, k + 1);
3939 left -= cur_size;
3940
3941 char right_char = cur_size == k + 1 ? 'b' : 'c';
3942 list.push_back(
3943 tgen::str("a{%d}%c", cur_size - 1, right_char).gen().to_std());
3944
3945 k++;
3946 }
3947 return tgen::shuffled(list);
3948}
3949
3950} // namespace hack
3951
3952/*********************
3953 * *
3954 * MISCELLANEOUS *
3955 * *
3956 *********************/
3957
3958namespace misc {
3959
3960// Generates a random balanced parentheses sequence with k '(' and k ')'.
3961// Valid meanst that for no prefix there are more ')' than '('.
3962// O(size).
3963inline std::string gen_parenthesis(int size) {
3964 tgen_ensure(size > 0 and size % 2 == 0,
3965 "misc: parenthesis: size must a positive even number");
3966
3967 int k = size / 2;
3968 std::string s;
3969 int open = 0, close = 0;
3970
3971 for (int i = 0; i < size; ++i) {
3972 if (open == k) {
3973 s += ')';
3974 ++close;
3975 continue;
3976 }
3977 if (open == close) {
3978 s += '(';
3979 ++open;
3980 continue;
3981 }
3982
3983 long long a = k - open, b = k - close, h = open - close;
3984
3985 // Probability of placing '(':
3986 // P('(') = (k - open) * (bal + 1) / (rem)
3987 // Derived from ballot numbers ratio.
3988 long long num = a * (h + 2);
3989 long long den = (a + b) * (h + 1);
3990
3991 if (next<long long>(1, den) <= num) {
3992 s += '(';
3993 ++open;
3994 } else {
3995 s += ')';
3996 ++close;
3997 }
3998 }
3999
4000 return s;
4001}
4002
4003} // namespace misc
4004
4005} // namespace tgen
C choose(const C &container, int k)
Chooses elements from container, as in a subsequence fixed length.
Definition tgen.h:747
C::value_type pick(const C &container)
Choses a random element from container.
Definition tgen.h:681
void shuffle(It first, It last)
Shuffles range inplace, for random_access_iterator.
Definition tgen.h:624
It::value_type pick(It first, It last)
Choses a random element from iterator range.
Definition tgen.h:671
T next(T right)
Returns a random number up to value.
Definition tgen.h:553
auto shuffled(const C &container)
Shuffles a container.
Definition tgen.h:643
size_t next_by_distribution(const std::vector< T > &distribution)
Returns random index with given probabilities.
Definition tgen.h:605
C::value_type pick_by_distribution(const C &container, std::vector< T > distribution)
Choses a random element with given probabilities.
Definition tgen.h:699
#define tgen_ensure(cond,...)
Ensures condition is true.
Definition tgen.h:101
T next(T left, T right)
Returns a random number in range.
Definition tgen.h:568
Inst shuffled(const Inst &inst)
Shuffles a list value.
Definition tgen.h:663
void shuffle(Inst &inst)
Shuffles a list value.
Definition tgen.h:635
Inst::value_type pick_by_distribution(const Inst &inst, const std::vector< T > &distribution)
Choses a random element from the list value.
Definition tgen.h:731
std::pair< std::string, std::string > unsigned_polynomial_hash_hack()
Returns two strings that force polynomial hash collision for power-of-two mod.
Definition tgen.h:3844
std::vector< std::string > string_set(int size)
List of strings that have high cost to insert in a std::set.
Definition tgen.h:3934
std::string abacaba(int n)
Returns the prefix of the infinite word "abacabad...".
Definition tgen.h:3827
std::vector< long long > std_unordered(int size)
List of integers that tries to force collision on std::unordered_set.
Definition tgen.h:3894
std::pair< std::string, std::string > polynomial_hash_hack(int alphabet_size, int base, int mod)
Returns two strings that force polynomial hash collision given base and mod.
Definition tgen.h:3858
std::vector< std::pair< int, int > > mo(int n, int q)
Query list that tries to force asymptotic worst-case for Mo's algorithm.
Definition tgen.h:3921
uint64_t prime_from(uint64_t left)
Computes smallest prime from given value.
Definition tgen.h:2394
uint64_t gen_divisor_count(uint64_t left, uint64_t right, int divisor_count)
Generates random number in range with a given prime number of divisors.
Definition tgen.h:2423
std::vector< int > gen_partition_fixed_size(int n, int k, int part_left=0, std::optional< int > part_right=std::nullopt)
Generates a random partition with fixed size of a number.
Definition tgen.h:2669
uint64_t totient(uint64_t n)
Euler's totient function.
Definition tgen.h:2254
uint64_t congruent_from(uint64_t left, std::vector< uint64_t > rems, std::vector< uint64_t > mods)
Computes smallest congruent from given value.
Definition tgen.h:2490
uint64_t congruent_upto(uint64_t right, uint64_t rem, uint64_t mod)
Computes largest congruent up to given value.
Definition tgen.h:2578
uint64_t gen_prime(uint64_t left, uint64_t right)
Generates a random prime in given range.
Definition tgen.h:2369
std::vector< uint64_t > factor(uint64_t n)
Factors a number into primes.
Definition tgen.h:2223
int num_divisors(uint64_t n)
Computes the number of divisors of a given number.
Definition tgen.h:2413
bool is_prime(uint64_t n)
Checks if a number is prime.
Definition tgen.h:1967
std::vector< int > gen_partition(int n, int part_left=1, std::optional< int > part_right=std::nullopt)
Generates a random partition of a number.
Definition tgen.h:2603
constexpr int FFT_MOD
FFT/NTT mod.
Definition tgen.h:2584
uint64_t gen_congruent(uint64_t left, uint64_t right, uint64_t rem, uint64_t mod)
Generates random number in range given a modular congruence.
Definition tgen.h:2480
uint64_t prime_upto(uint64_t right)
Computes largest prime up to given value.
Definition tgen.h:2403
uint64_t highly_composite_upto(uint64_t right)
Largest highly composite number up to given number.
Definition tgen.h:2359
uint64_t congruent_upto(uint64_t right, std::vector< uint64_t > rems, std::vector< uint64_t > mods)
Computes largest congruent up to given value.
Definition tgen.h:2538
std::vector< std::pair< uint64_t, int > > factor_by_prime(uint64_t n)
Factors a number into primes and its powers.
Definition tgen.h:2233
const std::vector< uint64_t > & fibonacci()
Fetches Fibonacci numbers.
Definition tgen.h:2587
uint64_t modular_inverse(uint64_t a, uint64_t mod)
Computes modular inverse.
Definition tgen.h:2248
uint64_t congruent_from(uint64_t left, uint64_t rem, uint64_t mod)
Computes smallest congruent from given value.
Definition tgen.h:2529
const std::vector< uint64_t > & highly_composites()
Fetches highly composite numbers.
Definition tgen.h:2319
uint64_t gen_congruent(uint64_t left, uint64_t right, std::vector< uint64_t > rems, std::vector< uint64_t > mods)
Generates random number in range given modular congruences.
Definition tgen.h:2436
std::pair< uint64_t, uint64_t > prime_gap_upto(uint64_t right)
Largest prime gap up to given number.
Definition tgen.h:2300
std::string gen_parenthesis(int size)
Generates a random valid parenthesis sequence.
Definition tgen.h:3963
T opt(const std::string &key, std::optional< T > default_value=std::nullopt)
Gets opt by key.
Definition tgen.h:1139
T opt(size_t index, std::optional< T > default_value=std::nullopt)
Gets opt by key.
Definition tgen.h:1125
bool has_opt(std::size_t index)
Checks if opt at some index exists.
Definition tgen.h:1107
bool has_opt(const std::string &key)
Checks if opt with with some key exists.
Definition tgen.h:1113
void set_cpp_version(int version)
Sets C++ version.
Definition tgen.h:903
void register_gen(std::optional< long long > seed=std::nullopt)
Sets up the generator without arguments.
Definition tgen.h:1166
void register_gen(int argc, char **argv)
Sets up the generator.
Definition tgen.h:1155
Distinct generator for containers.
Definition tgen.h:837
auto gen_list(int size)
Generates a list of several distinct elements.
Definition tgen.h:858
T gen()
Generates a distinct random element from the container.
Definition tgen.h:854
distinct_container(const C &container)
Creates distinct generator for elements of the given container.
Definition tgen.h:843
auto gen_all()
Generates all distinct elements left to generate.
Definition tgen.h:867
size_t size() const
Returns the number of elements left to generate.
Definition tgen.h:850
Distinct generator for integral ranges.
Definition tgen.h:788
auto gen_all()
Generates all distinct values left to generate.
Definition tgen.h:828
T gen()
Generates a distinct random value in the defined range.
Definition tgen.h:801
auto gen_list(int size)
Generates a list of several distinct values.
Definition tgen.h:819
distinct_range(T l, T r)
Creates distinct generator for values in given range.
Definition tgen.h:794
T size() const
Returns the number of values left to generate.
Definition tgen.h:797
Distinct generator for discrete uniform functions.
Definition tgen.h:235
distinct(Func func, Args... args)
Generates a distinct generator of a discrete uniform function.
Definition tgen.h:241
auto gen_list(int size)
Generates a list of several distinct values.
Definition tgen.h:288
bool empty()
Checks if there is nothing left to generate.
Definition tgen.h:299
auto gen_all()
Generates all distinct values left to generate.
Definition tgen.h:302
auto gen()
Generates a distinct value.
Definition tgen.h:276
Base class for generators (should not be instantiated).
Definition tgen.h:326
auto gen_list(int size, Args &&...args) const
Generates a list of several generation calls.
Definition tgen.h:329
auto gen_until(Pred predicate, int max_tries, Args &&...args) const
Generates a random value from the valid set until a condition is met.
Definition tgen.h:341
auto distinct(Args &&...args) const
Creates distinct generator for current generator.
Definition tgen.h:360
Base class for generator values (should not be instantiated).
Definition tgen.h:383
bool operator<(const Inst &rhs) const
Definition tgen.h:386
If type is defined for a subset of itself, for tgen generator value.
Definition tgen.h:418
If type is associative container.
Definition tgen.h:397
If type is a tgen generator value.
Definition tgen.h:406
If type is a list-like tgen generator value.
Definition tgen.h:410
List value.
Definition tgen.h:1320
int size() const
Returns the size of the list value.
Definition tgen.h:1333
value(const std::vector< T > &vec)
Creates a list value from a std::vector.
Definition tgen.h:1329
value & sort()
Sorts the value in non-decreasing order.
Definition tgen.h:1349
auto to_std() const
Converts the value to a std::vector.
Definition tgen.h:1388
value operator+(const value &rhs)
Concatenates two values.
Definition tgen.h:1370
value & separator(char sep)
Sets separator for printing.
Definition tgen.h:1363
T & operator[](int idx)
Accesses the value at some position of the value.
Definition tgen.h:1336
value & reverse()
Reverses the value.
Definition tgen.h:1356
List generator.
Definition tgen.h:1190
list & different(int idx_1, int idx_2)
Restricts generator s.t. values at two indices are different.
Definition tgen.h:1297
list & equal(int idx_1, int idx_2)
Restricts generator s.t. values at two indices are equal.
Definition tgen.h:1253
list & all_different()
Restricts generator s.t. all values are different.
Definition tgen.h:1312
list & equal_range(int left, int right)
Restricts generator s.t. all values at index range are equal.
Definition tgen.h:1276
list(int size, std::set< T > values)
Creates list generator defined by value set.
Definition tgen.h:1215
value gen() const
Generates a random value from the set of valid lists.
Definition tgen.h:1452
list & all_equal()
Restricts generator s.t. all values are equal.
Definition tgen.h:1285
list & different(std::set< int > indices)
Restricts generator s.t. all values in index set are different.
Definition tgen.h:1290
list & different_range(int left, int right)
Restricts generator s.t. all values at index range are different.
Definition tgen.h:1303
list(int size, T value_left, T value_right)
Creates list generator defined by size and range of values.
Definition tgen.h:1205
list & fix(int idx, T val)
Restricts generator s.t. value at index is fixed.
Definition tgen.h:1228
list & equal(std::set< int > indices)
Restricts generator s.t. all values in index set are equal.
Definition tgen.h:1266
Pair value.
Definition tgen.h:3528
T second() const
Returns the second element of a pair value.
Definition tgen.h:3540
value(const T &first, const T &second)
Creates a pair value from first and second values.
Definition tgen.h:3536
value(const std::pair< T, T > &pair)
Creates a pair value from a std::pair.
Definition tgen.h:3535
auto to_std() const
Converts the value to a std::pair.
Definition tgen.h:3554
T first() const
Returns the first element of a pair value.
Definition tgen.h:3539
value & separator(char sep)
Sets separator for printing.
Definition tgen.h:3543
Pair generator.
Definition tgen.h:3471
value gen() const
Generates a random value from the set of valid pairs.
Definition tgen.h:3567
pair & neq()
Restricts generator s.t. first is not equal to second.
Definition tgen.h:3498
pair & leq()
Restricts generator s.t. first is less than or equal to second.
Definition tgen.h:3516
pair & lt()
Restricts generator s.t. first is less than second.
Definition tgen.h:3504
pair & gt()
Restricts generator s.t. first is greater than second.
Definition tgen.h:3510
pair(T both_left, T both_right)
Creates pair generator defined by range of values for both first and second.
Definition tgen.h:3488
pair & eq()
Restricts generator s.t. first is equal to second.
Definition tgen.h:3492
pair(T first_left, T first_right, T second_left, T second_right)
Creates pair generator defined by range of values for first and second.
Definition tgen.h:3479
pair & geq()
Restricts generator s.t. first is greater than or equal to second.
Definition tgen.h:3522
Permutation value.
Definition tgen.h:1757
value & add_1()
Adds 1 for printing.
Definition tgen.h:1842
std::vector< int > to_std() const
Converts the value to a std::vector.
Definition tgen.h:1858
const int & operator[](int idx) const
Returns the value at some position of the value.
Definition tgen.h:1786
value & sort()
Sorts the value in non-decreasing order.
Definition tgen.h:1810
int parity() const
Parity of the permutation.
Definition tgen.h:1794
value & reverse()
Reverses the value.
Definition tgen.h:1818
value(const std::vector< int > &vec)
Creates a permutation value from a std::vector.
Definition tgen.h:1765
int size() const
Returns the size of the permutation value.
Definition tgen.h:1783
value & inverse()
Inverse of the permutation.
Definition tgen.h:1825
value & separator(char sep)
Sets separator for printing.
Definition tgen.h:1835
Permutation generator.
Definition tgen.h:1725
value gen() const
Generates a random value from the set of valid permutations.
Definition tgen.h:1863
permutation & cycles(const std::vector< int > &cycle_sizes)
Restricts generator s.t. cycle sizes are fixed.
Definition tgen.h:1744
permutation(int size)
Creates permutation generator defined by size.
Definition tgen.h:1731
permutation & fix(int idx, int val)
Restricts generator s.t. value at index is fixed.
Definition tgen.h:1736
Printer helper for standard types.
Definition tgen.h:429
print(const T &val, char sep=' ')
Cretes a printer object.
Definition tgen.h:432
Printer helper for standard types, printing on a new line.
Definition tgen.h:531
println(const T &val, char sep=' ')
Cretes a printer object that prints on a new line.
Definition tgen.h:533
String value.
Definition tgen.h:3179
value & lowercase()
Sets all characters to lowercase.
Definition tgen.h:3222
value & reverse()
Reverses the value.
Definition tgen.h:3215
int size() const
Returns the size of the string value.
Definition tgen.h:3192
value operator+(const value &rhs)
Concatenates two values.
Definition tgen.h:3238
value(const std::string &str)
Creates a string value from a std::string.
Definition tgen.h:3187
char & operator[](int idx)
Accesses the character at some position of the value.
Definition tgen.h:3195
value & uppercase()
Sets all characters to uppercase.
Definition tgen.h:3230
std::string to_std() const
Converts the value to a std::string.
Definition tgen.h:3246
value & sort()
Sorts the characters in non-decreasing order.
Definition tgen.h:3208
String generator.
Definition tgen.h:3076
str & different(int idx_1, int idx_2)
Restricts generator s.t. characters at two indices are different.
Definition tgen.h:3158
str & palindrome(int left, int right)
Restricts generator s.t. range is a palindrome.
Definition tgen.h:3134
value gen() const
Generates a random value from the set of valid strings.
Definition tgen.h:3252
str(int size, char value_left='a', char value_right='z')
Creates string generator defined by size and range of characters.
Definition tgen.h:3083
str & different(std::set< int > indices)
Restricts generator s.t. all characters in index set are different.
Definition tgen.h:3151
str(const std::string &regex, Args &&...args)
Creates string generator defined by regex.
Definition tgen.h:3091
str & equal(int idx_1, int idx_2)
Restricts generator s.t. characters at two indices are equal.
Definition tgen.h:3113
str & equal(std::set< int > indices)
Restricts generator s.t. all characters in index set are equal.
Definition tgen.h:3106
str & equal_range(int left, int right)
Restricts generator s.t. all characters at index range are equal.
Definition tgen.h:3120
str & fix(int idx, char character)
Restricts generator s.t. character at index is fixed.
Definition tgen.h:3099
str & all_equal()
Restricts generator s.t. all values are equal.
Definition tgen.h:3127
str & different_range(int left, int right)
Restricts generator s.t. all characters at index range are different.
Definition tgen.h:3165
str & palindrome()
Restricts generator s.t. string is a palindrome.
Definition tgen.h:3144
str & all_different()
Restricts generator s.t. all characters are different.
Definition tgen.h:3172
str(int size, std::set< char > chars)
Creates string generator defined by character set.
Definition tgen.h:3088