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 <iostream>
27#include <map>
28#include <optional>
29#include <queue>
30#include <random>
31#include <set>
32#include <sstream>
33#include <stdexcept>
34#include <string>
35#include <vector>
36
37namespace tgen {
38
39/**************************
40 * *
41 * GENERAL OPERATIONS *
42 * *
43 **************************/
44
45/*
46 * Error handling.
47 */
48
49namespace _detail {
50
51inline void throw_assertion_error(const std::string &condition,
52 const std::string &msg) {
53 throw std::runtime_error("tgen: " + msg + " (assertion `" + condition +
54 "` failed)");
55}
56inline void throw_assertion_error(const std::string &condition) {
57 throw std::runtime_error("tgen: assertion `" + condition + "` failed");
58}
59inline std::runtime_error error(const std::string &msg) {
60 return std::runtime_error("tgen: " + msg);
61}
62inline std::runtime_error contradiction_error(const std::string &type,
63 const std::string &msg = "") {
64 // Tried to generate a contradicting sequence.
65 std::string error_msg = "invalid " + type + " (contradicting constraints)";
66 if (!msg.empty())
67 error_msg += ": " + msg;
68 return error(error_msg);
69}
70template <typename T>
71std::runtime_error there_is_no_in_range_error(const std::string &type, T l,
72 T r) {
73 return error("there is no " + type + " in range [" + std::to_string(l) +
74 ", " + std::to_string(r) + "]");
75}
76template <typename T>
77std::runtime_error there_is_no_upto_error(const std::string &type, T r) {
78 return error("there is no " + type + " up to " + std::to_string(r));
79}
80inline void tgen_ensure_against_bug(bool cond) {
81 if (!cond)
82 throw std::runtime_error(
83 "tgen: THERE IS A BUG IN TGEN; PLEASE CONTACT MAINTAINERS");
84}
85
86// Ensures condition is true, with nice debug.
87#define tgen_ensure(cond, ...)
88 if (!(cond))
89 tgen::_detail::throw_assertion_error(#cond, ##__VA_ARGS__);
90
91// Registering checks.
92inline bool registered = false;
93inline void ensure_registered() {
94 tgen_ensure(registered,
95 "tgen was not registered! You should call "
96 "tgen::register_gen(argc, argv) before running tgen functions");
97}
98
99} // namespace _detail
100
101/*
102 * Easier printing.
103 */
104
105namespace _detail {
106
107// Template magic to detect types in compile tiem.
108
109// Detects containers != std::string.
110template <typename T, typename = void> struct is_container : std::false_type {};
111template <typename T>
112struct is_container<T, std::void_t<typename T::value_type,
113 decltype(std::begin(std::declval<T>())),
114 decltype(std::end(std::declval<T>()))>>
115 : std::true_type {};
116template <> struct is_container<std::string> : std::false_type {};
117// Detects std::pair.
118template <typename T> struct is_pair : std::false_type {};
119template <typename A, typename B>
120struct is_pair<std::pair<A, B>> : std::true_type {};
121// Detects std::tuple.
122template <typename T> struct is_tuple : std::false_type {};
123template <typename... Ts>
124struct is_tuple<std::tuple<Ts...>> : std::true_type {};
125// Detects scalar (printed atomically).
126template <typename T>
129 !is_pair<T>::value> {};
130// Detects complex container.
131template <typename T>
135// Detects complex std::pair.
136template <typename T> struct is_pair_multiline : std::false_type {};
137template <typename A, typename B>
138struct is_pair_multiline<std::pair<A, B>>
140// Detects complex std::tuple.
141template <typename Tuple> struct is_tuple_multiline : std::false_type {};
142template <typename... Ts>
143struct is_tuple_multiline<std::tuple<Ts...>>
144 : std::bool_constant<(!is_scalar<Ts>::value or ...)> {};
145
146} // namespace _detail
147
148// Struct to print standard types to std::ostream;
149struct print {
150 std::string s;
151
152 template <typename T> print(const T &x) {
153 std::ostringstream oss;
154 write(oss, x);
155 s = oss.str();
156 }
157 template <typename T> print(const std::initializer_list<T> &il) {
158 std::ostringstream oss;
159 write(oss, std::vector<T>(il.begin(), il.end()));
160 s = oss.str();
161 }
162 template <typename T>
163 print(const std::initializer_list<std::initializer_list<T>> &il) {
164 std::ostringstream oss;
165 std::vector<std::vector<T>> mat;
166 for (const auto &i : il)
167 mat.push_back(i);
168 write(oss, mat);
169 s = oss.str();
170 }
171
172 template <typename T> void write(std::ostream &os, const T &x) {
173 if constexpr (_detail::is_pair<T>::value) {
174 if constexpr (_detail::is_pair_multiline<T>::value) {
175 write(os, x.first);
176 os << '\n';
177 write(os, x.second);
178 } else {
179 write(os, x.first);
180 os << ' ';
181 write(os, x.second);
182 }
183 } else if constexpr (_detail::is_tuple<T>::value)
184 write_tuple(os, x);
185 else if constexpr (_detail::is_container<T>::value)
186 write_container(os, x);
187 else
188 os << x;
189 }
190
191 // Writes container, checking separator.
192 template <typename C> void write_container(std::ostream &os, const C &c) {
193 bool first = true;
194
195 for (const auto &e : c) {
196 if (!first)
197 os << (_detail::is_container_multiline<C>::value ? '\n' : ' ');
198 first = false;
199 write(os, e);
200 }
201 }
202
203 // Writes tuple, checking separator.
204 template <typename Tuple, size_t... I>
205 void write_tuple_impl(std::ostream &os, const Tuple &tp,
206 std::index_sequence<I...>) {
207 bool first = true;
208 ((os << (first ? (first = false, "")
209 : (_detail::is_tuple_multiline<Tuple>::value ? "\n"
210 : " ")),
211 write(os, std::get<I>(tp))),
212 ...);
213 }
214 template <typename T> void write_tuple(std::ostream &os, const T &tp) {
215 write_tuple_impl(os, tp,
216 std::make_index_sequence<std::tuple_size<T>::value>{});
217 }
218
219 friend std::ostream &operator<<(std::ostream &out, const print &pr) {
220 return out << pr.s;
221 }
222};
223
224// Prints in a new line.
225template <typename T> inline print println(const T &x) {
226 print p(x);
227 p.s += '\n';
228 return p;
229}
230template <typename T> inline print println(const std::initializer_list<T> &il) {
231 print p(il);
232 p.s += '\n';
233 return p;
234}
235template <typename T>
236inline print
237println(const std::initializer_list<std::initializer_list<T>> &il) {
238 print p(il);
239 p.s += '\n';
240 return p;
241}
242
243/*
244 * Global random operations.
245 */
246
247namespace _detail {
248
249inline std::mt19937 rng;
250
251// Base struct for generators.
252template <typename Gen> struct gen_base {
253 // Calls the generator until predicate is true.
254 template <typename Pred, typename... Args>
255 auto gen_until(Pred predicate, int max_tries, Args &&...args) const {
256 for (int i = 0; i < max_tries; ++i) {
257 auto inst = static_cast<const Gen *>(this)->gen(
258 std::forward<Args>(args)...);
259
260 if (predicate(inst))
261 return inst;
262 }
263
264 throw error("could not generate instance matching predicate");
265 }
266 template <typename Pred, typename T, typename... Args>
267 auto gen_until(Pred predicate, int max_tries, std::initializer_list<T> il,
268 Args &&...args) const {
269 return gen_until(predicate, max_tries, std::vector<T>(il),
270 std::forward<Args>(args)...);
271 }
272
273 // Nice error for `std::cout << generator`.
274 friend std::ostream &operator<<(std::ostream &out, const gen_base &) {
275 static_assert(
276 false,
277 "you cannot print a generator. Maybe you forgot to call `gen()`?");
278 return out;
279 }
280};
281
282template <typename T, typename = void>
283struct is_associative_container : std::false_type {};
284template <typename T>
285struct is_associative_container<
286 T, std::void_t<typename T::key_type, typename T::key_compare>>
287 : std::true_type {};
288
289// Tag used to identify generator instance types (sequence::instance,
290// permutation::instance).
292template <typename T, typename = void>
293struct is_generator_instance : std::false_type {};
294template <typename T>
295struct is_generator_instance<T, std::void_t<typename T::_tgen_instance_tag>>
296 : std::is_same<typename T::_tgen_instance_tag, generator_instance_tag> {};
297
298} // namespace _detail
299
300// Returns a random number in [l, r].
301// O(1).
302template <typename T> T next(T l, T r) {
303 _detail::ensure_registered();
304 tgen_ensure(l <= r, "range for `next` bust be valid");
305 if constexpr (std::is_integral_v<T>)
306 return std::uniform_int_distribution<T>(l, r)(_detail::rng);
307 else if constexpr (std::is_floating_point_v<T>)
308 return std::uniform_real_distribution<T>(l, r)(_detail::rng);
309 else
310 throw _detail::error("invalid type for next (" +
311 std::string(typeid(T).name()) + ")");
312}
313
314// Shuffles [first, last) inplace uniformly, for RandomAccessIterator.
315// O(|container|).
316template <typename It> void shuffle(It first, It last) {
317 if (first == last)
318 return;
319
320 for (It i = first + 1; i != last; ++i)
321 std::iter_swap(i, first + next(0, static_cast<int>(i - first)));
322}
323
324// Shuffles container uniformly.
325// O(|container|).
326template <typename C,
327 std::enable_if_t<!_detail::is_associative_container<C>::value and
328 !_detail::is_generator_instance<C>::value,
329 int> = 0>
330[[nodiscard]] C shuffled(const C &container) {
331 auto new_container = container;
332 shuffle(new_container.begin(), new_container.end());
333 return new_container;
334}
335template <typename C, std::enable_if_t<
336 _detail::is_associative_container<C>::value, int> = 0>
337[[nodiscard]] std::vector<typename C::value_type> shuffled(const C &container) {
338 return shuffled(std::vector<typename C::value_type>(container.begin(),
339 container.end()));
340}
341template <typename T>
342[[nodiscard]] std::vector<T> shuffled(const std::initializer_list<T> &il) {
343 return shuffled(std::vector<T>(il.begin(), il.end()));
344}
345
346// Shuffles sequence/permutation instance uniformly.
347// O(n).
348template <
349 typename Inst,
350 std::enable_if_t<_detail::is_generator_instance<Inst>::value, int> = 0>
351Inst shuffled(const Inst &inst) {
352 Inst new_inst = inst;
353 tgen::shuffle(new_inst.vec_.begin(), new_inst.vec_.end());
354 return new_inst;
355}
356
357// Returns a random element from [first, last) uniformly.
358// O(1) for random_access_iterator, O(|last - first|) otherwise.
359template <typename It> typename It::value_type any(It first, It last) {
360 int size = std::distance(first, last);
361 It it = first;
362 std::advance(it, next(0, size - 1));
363 return *it;
364}
365
366// Returns a random element from container uniformly.
367// O(1) for random_access_iterator, O(|container|) otherwise.
368template <typename C,
369 std::enable_if_t<!_detail::is_generator_instance<C>::value, int> = 0>
370typename C::value_type any(const C &container) {
371 return any(container.begin(), container.end());
372}
373template <typename T> T any(const std::initializer_list<T> &il) {
374 return any(std::vector<T>(il.begin(), il.end()));
375}
376
377// Choses any value from sequence/permutation instance uniformly.
378// O(1).
379template <
380 typename Inst,
381 std::enable_if_t<_detail::is_generator_instance<Inst>::value, int> = 0>
382typename Inst::value_type any(const Inst &inst) {
383 return inst.vec_[next<int>(0, inst.vec_.size() - 1)];
384}
385
386// Chooses k values uniformly from container, as in a subsequence of size k.
387// Returns a copy. O(|container|).
388template <typename C,
389 std::enable_if_t<!_detail::is_generator_instance<C>::value, int> = 0>
390C choose(int k, const C &container) {
391 tgen_ensure(0 < k and k <= static_cast<int>(container.size()),
392 "number of elements to choose must be valid");
393 std::vector<typename C::value_type> new_vec;
394 C new_container;
395 int need = k, left = container.size();
396 for (auto cur_it = container.begin(); cur_it != container.end(); ++cur_it) {
397 if (next(1, left--) <= need) {
398 new_container.insert(new_container.end(), *cur_it);
399 need--;
400 }
401 }
402 return new_container;
403}
404template <typename T>
405std::vector<T> choose(int k, const std::initializer_list<T> &il) {
406 return choose(k, std::vector<T>(il.begin(), il.end()));
407}
408
409// Chooses k values uniformly from sequence/permutation instance, as in a
410// subsequence of size k.
411// O(n).
412template <
413 typename Inst,
414 std::enable_if_t<_detail::is_generator_instance<Inst>::value, int> = 0>
415Inst choose(int k, const Inst &inst) {
416 tgen_ensure(0 < k and k <= static_cast<int>(inst.vec_.size()),
417 "number of elements to choose must be valid");
418 std::vector<typename Inst::value_type> new_vec;
419 int need = k;
420 for (int i = 0; need > 0; ++i) {
421 int left = inst.vec_.size() - i;
422 if (next(1, left) <= need) {
423 new_vec.push_back(inst.vec_[i]);
424 need--;
425 }
426 }
427 return Inst(new_vec);
428}
429
430/************
431 * *
432 * OPTS *
433 * *
434 ************/
435
436/*
437 * Opts - options given to the generator.
438 *
439 * Incompatible with testlib.
440 *
441 * Opts are a list of either positional or named options.
442 *
443 * Named options is given in one of the following formats:
444 * 1) -keyname=value or --keyname=value (ex. -n=10 , --test-count=20)
445 * 2) -keyname value or --keyname value (ex. -n 10 , --test-count 20)
446 *
447 * Positional options are number from 0 sequentially.
448 * For example, for "10 -n=20 str" positional option 1 is the string "str".
449 */
450
451namespace _detail {
452
453inline std::vector<std::string>
454 pos_opts; // Dictionary containing the positional parsed opts.
455inline std::map<std::string, std::string>
456 named_opts; // Global dictionary the named parsed opts.
457
458template <typename T> T get_opt(const std::string &value) {
459 try {
460 if constexpr (std::is_same_v<T, bool>) {
461 if (value == "true" or value == "1")
462 return true;
463 if (value == "false" or value == "0")
464 return false;
465 } else if constexpr (std::is_integral_v<T>) {
466 if constexpr (std::is_unsigned_v<T>)
467 return static_cast<T>(std::stoull(value));
468 else
469 return static_cast<T>(std::stoll(value));
470 } else if constexpr (std::is_floating_point_v<T>)
471 return static_cast<T>(std::stold(value));
472 else
473 return value; // default: std::string
474 } catch (...) {
475 }
476
477 throw _detail::error("invalid value `" + value + "` for type " +
478 typeid(T).name());
479}
480
481inline void parse_opts(int argc, char **argv) {
482 // Parses the opts into `pos_opts` vector and `named_opts`
483 // map. Starting from 1 to ignore the name of the executable.
484 for (int i = 1; i < argc; ++i) {
485 std::string key(argv[i]);
486
487 if (key[0] == '-') {
488 tgen_ensure(key.size() > 1,
489 "invalid opt (" + std::string(argv[i]) + ")");
490 if ('0' <= key[1] and key[1] <= '9') {
491 // This case is a positional negative number argument
492 _detail::pos_opts.push_back(key);
493 continue;
494 }
495
496 // pops first char '-'
497 key = key.substr(1);
498 } else {
499 // This case is a positional argument that does not start with '-'
500 _detail::pos_opts.push_back(key);
501 continue;
502 }
503
504 // Pops a possible second char '-'.
505 if (key[0] == '-') {
506 tgen_ensure(key.size() > 1,
507 "invalid opt (" + std::string(argv[i]) + ")");
508
509 // pops first char '-'
510 key = key.substr(1);
511 }
512
513 // Assumes that, if it starts with '-' and second char is not a digit,
514 // then it is a <key, value> pair.
515 // 1 or 2 chars '-' have already been poped.
516
517 std::size_t eq = key.find('=');
518 if (eq != std::string::npos) {
519 // This is the '--key=value' case.
520 std::string value = key.substr(eq + 1);
521 key = key.substr(0, eq);
522 tgen_ensure(!key.empty() and !value.empty(),
523 "expected non-empty key/value in opt (" +
524 std::string(argv[1]));
525 tgen_ensure(_detail::named_opts.count(key) == 0,
526 "cannot have repeated keys");
527 _detail::named_opts[key] = value;
528 } else {
529 // This is the '--key value' case.
530 tgen_ensure(_detail::named_opts.count(key) == 0,
531 "cannot have repeated keys");
532 tgen_ensure(argv[i + 1], "value cannot be empty");
533 _detail::named_opts[key] = std::string(argv[i + 1]);
534 ++i;
535 }
536 }
537}
538
539inline void set_seed(int argc, char **argv) {
540 std::vector<uint32_t> seed;
541
542 // Starting from 1 to ignore the name of the executable.
543 for (int i = 1; i < argc; ++i) {
544 // We append the number of chars, and then the list of chars.
545 int size_pos = seed.size();
546 seed.push_back(0);
547 for (char *s = argv[i]; *s != '\0'; ++s) {
548 ++seed[size_pos];
549 seed.push_back(*s);
550 }
551 }
552 std::seed_seq seq(seed.begin(), seed.end());
553 _detail::rng.seed(seq);
554}
555
556} // namespace _detail
557
558// Returns true if there is an opt at a given index.
559inline bool has_opt(std::size_t index) {
560 tgen::_detail::ensure_registered();
561 return 0 <= index and index < _detail::pos_opts.size();
562}
563
564// Returns true if there is an opt with a given key.
565inline bool has_opt(const std::string &key) {
566 tgen::_detail::ensure_registered();
567 return _detail::named_opts.count(key) != 0;
568}
569
570// Returns the parsed opt by a given key. If no opts with the given key are
571// found, returns the given default_value.
572template <typename T, typename Key>
573T opt(const Key &key, std::optional<T> default_value = std::nullopt) {
574 tgen::_detail::ensure_registered();
575 if constexpr (std::is_same_v<Key, int>) {
576 if (!has_opt(key)) {
577 if (default_value)
578 return *default_value;
579 throw _detail::error("cannot find key with index " +
580 std::to_string(key));
581 }
582 return _detail::get_opt<T>(_detail::pos_opts[key]);
583 } else { // std::string
584 if (!has_opt(key)) {
585 if (default_value)
586 return *default_value;
587 throw _detail::error("cannot find key with key " +
588 std::string(key));
589 }
590 return _detail::get_opt<T>(_detail::named_opts[key]);
591 }
592}
593
594// Registers generator by initializing rnd and parsing opts.
595inline void register_gen(int argc, char **argv) {
596 _detail::set_seed(argc, argv);
597
598 _detail::pos_opts.clear();
599 _detail::named_opts.clear();
600 _detail::parse_opts(argc, argv);
601
602 _detail::registered = true;
603}
604
605/****************
606 * *
607 * SEQUENCE *
608 * *
609 ****************/
610
611/*
612 * Sequence generator.
613 */
614
615template <typename T> struct sequence : _detail::gen_base<sequence<T>> {
616 int size_; // Size of sequence.
617 T value_l_, value_r_; // Range of defined values.
618 std::set<T> values_; // Set of values. If empty, use range. if not,
619 // represents the possible values, and the range
620 // represents the index in this set)
621 std::map<T, int>
622 value_idx_in_set_; // Index of every value in the set above.
623 std::vector<std::pair<T, T>> val_range_; // Range of values of each index.
624 std::vector<std::vector<int>> neigh_; // Adjacency list of equality.
625 std::vector<std::set<int>>
626 distinct_constraints_; // All distinct constraints.
627
628 // Creates generator for sequences of size 'size', with random T in [l, r].
629 sequence(int size, T value_l, T value_r)
630 : size_(size), value_l_(value_l), value_r_(value_r), neigh_(size) {
631 tgen_ensure(size_ > 0, "size must be positive");
632 tgen_ensure(value_l_ <= value_r_, "value range must be valid");
633 for (int i = 0; i < size_; ++i)
634 val_range_.emplace_back(value_l_, value_r_);
635 }
636
637 // Creates sequence with value set.
638 sequence(int size, std::set<T> values)
639 : size_(size), values_(values), neigh_(size) {
640 tgen_ensure(size_ > 0, "size must be positive");
641 tgen_ensure(!values.empty(), "value set must be non-empty");
642 value_l_ = 0, value_r_ = values.size() - 1;
643 for (int i = 0; i < size_; ++i)
644 val_range_.emplace_back(value_l_, value_r_);
645 int idx = 0;
646 for (T value : values_)
647 value_idx_in_set_[value] = idx++;
648 }
649
650 // Restricts sequences for sequence[idx] = value.
651 sequence &set(int idx, T value) {
652 tgen_ensure(0 <= idx and idx < size_, "index must be valid");
653 if (values_.size() == 0) {
654 auto &[left, right] = val_range_[idx];
655 if (left == right and value_l_ != value_r_) {
656 tgen_ensure(left == value,
657 "must not set to two different values");
658 } else {
659 tgen_ensure(left <= value and value <= right,
660 "value must be in the defined range");
661 }
662 left = right = value;
663 } else {
664 tgen_ensure(values_.count(value),
665 "value must be in the set of values");
666 auto &[left, right] = val_range_[idx];
667 int new_val = value_idx_in_set_[value];
668 tgen_ensure(left <= new_val and new_val <= right,
669 "must not set to two different values");
670 left = right = new_val;
671 }
672 return *this;
673 }
674
675 // Restricts sequences for sequence[idx_1] = sequence[idx_2].
676 sequence &equal(int idx_1, int idx_2) {
677 tgen_ensure(0 <= std::min(idx_1, idx_2) and
678 std::max(idx_1, idx_2) < size_,
679 "indices must be valid");
680 if (idx_1 == idx_2)
681 return *this;
682
683 neigh_[idx_1].push_back(idx_2);
684 neigh_[idx_2].push_back(idx_1);
685 return *this;
686 }
687
688 // Restricts sequences for sequence[left..right] to have all equal values.
689 sequence &equal_range(int left, int right) {
690 tgen_ensure(0 <= left and left <= right and right < size_,
691 "range indices bust be valid");
692 for (int i = left; i < right; ++i)
693 equal(i, i + 1);
694 return *this;
695 }
696
697 // Restricts sequences for sequence[S] to be distinct, for given subset S of
698 // indices.
699 // You can not add two of these restrictions with intersection.
700 sequence &distinct(std::set<int> indices) {
701 if (!indices.empty())
702 distinct_constraints_.push_back(indices);
703 return *this;
704 }
705
706 // Restricts sequences for sequence[idx_1] != sequence[idx_2].
707 sequence &different(int idx_1, int idx_2) {
708 std::set<int> indices = {idx_1, idx_2};
709 return distinct(indices);
710 }
711
712 // Restricts sequences with distinct elements.
714 std::vector<int> indices(size_);
715 std::iota(indices.begin(), indices.end(), 0);
716 return distinct(std::set<int>(indices.begin(), indices.end()));
717 }
718
719 // Sequence instance.
720 // Operations on an instance are not random.
721 struct instance {
722 using _tgen_instance_tag = _detail::generator_instance_tag;
723 using value_type = T; // Value type, for templates.
724 using std_type = std::vector<T>; // std type for instance.
725 std::vector<T> vec_; // Sequence.
726
727 instance(const std::vector<T> &vec) : vec_(vec) {}
728 instance(const std::initializer_list<T> &il)
729 : vec_(il.begin(), il.end()) {}
730
731 // Fetches size.
732 int size() const { return vec_.size(); }
733
734 // Fetches position idx.
735 T &operator[](int idx) { return vec_[idx]; }
736 const T &operator[](int idx) const { return vec_[idx]; }
737
738 // Sorts values in non-decreasing order.
739 // O(n log n).
741 std::sort(vec_.begin(), vec_.end());
742 return *this;
743 }
744
745 // Reverses sequence.
746 // O(n).
748 std::reverse(vec_.begin(), vec_.end());
749 return *this;
750 }
751
752 // Concatenates two instances.
753 // Linear.
755 std::vector<T> new_vec = vec_;
756 for (int i = 0; i < rhs.size(); ++i)
757 new_vec.push_back(rhs[i]);
758 return instance(new_vec);
759 }
760
761 // Prints to std::ostream, separated by spaces.
762 friend std::ostream &operator<<(std::ostream &out,
763 const instance &inst) {
764 for (int i = 0; i < inst.size(); ++i) {
765 if (i > 0)
766 out << ' ';
767 out << inst[i];
768 }
769 return out;
770 }
771
772 // Gets a std::vector representing the instance.
773 std::vector<T> to_std() const { return vec_; }
774 };
775
776 // Generates a uniformly random list of k distinct values in `[value_l,
777 // value_r]`, such that no value is in `forbidden_values`.
778 std::vector<T>
779 generate_distinct_values(int k, const std::set<T> &forbidden_values) const {
780 for (auto forbidden : forbidden_values)
781 tgen_ensure(value_l_ <= forbidden and forbidden <= value_r_);
782 // We generate our numbers in the range [0, num_available) with
783 // num_available = (r-l+1)-(forbidden_values.size()), and then map them
784 // to the correct range. We will run k steps of Fisher–Yates, using a
785 // map to store a virtual sequence that starts with a[i] = i.
786 T num_available = (value_r_ - value_l_ + 1) - forbidden_values.size();
787 if (num_available < k)
788 throw _detail::error(
789 "failed to generate sequence: complex constraints");
790 std::map<T, T> virtual_list;
791 std::vector<T> gen_list;
792 for (int i = 0; i < k; ++i) {
793 T j = next<T>(i, num_available - 1);
794 T vj = virtual_list.count(j) ? virtual_list[j] : j;
795 T vi = virtual_list.count(i) ? virtual_list[i] : i;
796
797 virtual_list[j] = vi, virtual_list[i] = vj;
798
799 gen_list.push_back(virtual_list[i]);
800 }
801
802 // Shifts back to correct range, but there might still be values
803 // that we can not use.
804 for (T &value : gen_list)
805 value += value_l_;
806
807 // Now for every generated value, we shift it by how many forbidden
808 // values are <= to it.
809 std::vector<std::pair<T, int>> values_sorted;
810 for (std::size_t i = 0; i < gen_list.size(); ++i)
811 values_sorted.emplace_back(gen_list[i], i);
812 // We iterate through them in increasing order.
813 std::sort(values_sorted.begin(), values_sorted.end());
814 auto cur_it = forbidden_values.begin();
815 int smaller_forbidden_count = 0;
816 for (auto [val, idx] : values_sorted) {
817 while (cur_it != forbidden_values.end() and
818 *cur_it <= val + smaller_forbidden_count)
819 ++cur_it, ++smaller_forbidden_count;
820 gen_list[idx] += smaller_forbidden_count;
821 }
822
823 return gen_list;
824 }
825
826 // Generates sequence instance.
827 // O(n log n).
828 instance gen() const {
829 std::vector<T> vec(size_);
830 std::vector<bool> defined_idx(
831 size_, false); // For every index, if it has been set in `vec`.
832
833 std::vector<int> comp_id(size_, -1); // Component id of each index.
834 std::vector<std::vector<int>> comp(size_); // Component of each comp-id.
835 int comp_count = 0; // Number of different components.
836
837 // Defines value of entire component.
838 auto define_comp = [&](int cur_comp, T val) {
839 for (int idx : comp[cur_comp]) {
840 tgen_ensure(!defined_idx[idx]);
841 vec[idx] = val;
842 defined_idx[idx] = true;
843 }
844 };
845
846 // Groups = components.
847 {
848 std::vector<bool> vis(size_, false); // Visited for each index.
849 for (int idx = 0; idx < size_; ++idx)
850 if (!vis[idx]) {
851 T new_value;
852 bool value_defined = false;
853
854 // BFS to visit the connected component, grouping equal
855 // values.
856 std::queue<int> q({idx});
857 vis[idx] = true;
858 std::vector<int> component;
859 while (!q.empty()) {
860 int cur_idx = q.front();
861 q.pop();
862
863 component.push_back(cur_idx);
864
865 // Checks value.
866 auto [l, r] = val_range_[cur_idx];
867 if (l == r) {
868 if (!value_defined) {
869 // We found the value.
870 value_defined = true;
871 new_value = l;
872 } else if (new_value != l) {
873 // We found a contradiction
874 throw _detail::contradiction_error(
875 "sequence",
876 "tried to set value to `" +
877 std::to_string(new_value) +
878 "`, but it was already set as `" +
879 std::to_string(l) + "`");
880 }
881 }
882
883 for (int nxt_idx : neigh_[cur_idx]) {
884 if (!vis[nxt_idx]) {
885 vis[nxt_idx] = true;
886 q.push(nxt_idx);
887 }
888 }
889 }
890
891 // Group entire component, checking if value is defined.
892 for (int cur_idx : component) {
893 comp_id[cur_idx] = comp_count;
894 comp[comp_id[cur_idx]].push_back(cur_idx);
895 }
896
897 // Sets value if needed.
898 if (value_defined)
899 define_comp(comp_count, new_value);
900
901 ++comp_count;
902 }
903 }
904
905 // Initial parsing of distinct constraints.
906 std::vector<std::set<int>> distinct_containing_comp_idx(comp_count);
907 {
908 int dist_id = 0;
909 for (const std::set<int> &distinct : distinct_constraints_) {
910 // Checks if there are too many distinct values.
911 if (static_cast<uint64_t>(distinct.size() - 1) +
912 static_cast<uint64_t>(value_l_) >
913 static_cast<uint64_t>(value_r_))
914 throw _detail::contradiction_error(
915 "sequence",
916 "tried to generate " + std::to_string(distinct.size()) +
917 " distinct values, but the maximum is " +
918 std::to_string(value_r_ - value_l_ + 1));
919
920 // Checks if two values in same component are marked as
921 // different.
922 std::set<int> comp_ids;
923 for (int idx : distinct) {
924 if (comp_ids.count(comp_id[idx]))
925 throw _detail::contradiction_error(
926 "sequence", "tried to set two indices as equal and "
927 "different");
928 comp_ids.insert(comp_id[idx]);
929
930 distinct_containing_comp_idx[comp_id[idx]].insert(dist_id);
931 }
932 ++dist_id;
933 }
934 }
935
936 // If some value is in >= 3 sets, then there is a cycle.
937 for (auto &distinct_containing : distinct_containing_comp_idx)
938 if (distinct_containing.size() >= 3)
939 throw _detail::error(
940 "failed to generate sequence: complex constraints");
941
942 std::vector<bool> vis_distinct(distinct_constraints_.size(), false);
943 std::vector<bool> initially_defined_comp_idx(comp_count, false);
944
945 // Fills the value in a tree defined by distinct constraints.
946 auto define_tree = [&](int distinct_id) {
947 // The set `distinct_constraints_[distinct_id]` can have some values
948 // that are defined.
949
950 // Generates set of already defined values.
951 std::set<T> defined_values;
952 for (int idx : distinct_constraints_[distinct_id])
953 if (defined_idx[idx]) {
954 // Checks if two values in `distinct_constraints_[dist_id]`
955 // have been set to the same value
956 if (defined_values.count(vec[idx]))
957 throw _detail::contradiction_error(
958 "sequence",
959 "tried to set two indices as equal and different");
960
961 defined_values.insert(vec[idx]);
962 }
963
964 // Generates values in this root distinct constraint.
965 {
966 int new_value_count =
967 distinct_constraints_[distinct_id].size() -
968 static_cast<int>(defined_values.size());
969 std::vector<T> generated_values =
970 generate_distinct_values(new_value_count, defined_values);
971 auto val_it = generated_values.begin();
972 for (int idx : distinct_constraints_[distinct_id])
973 if (defined_idx[idx]) {
974 // The root can cover these components, but there should
975 // not be any other defined in this tree.
976 initially_defined_comp_idx[comp_id[idx]] = false;
977 } else {
978 define_comp(comp_id[idx], *val_it);
979 ++val_it;
980 }
981 }
982
983 // BFS on the tree of distinct constraints.
984 std::queue<std::pair<int, int>> q; // {id, parent id}
985 q.emplace(distinct_id, -1);
986 vis_distinct[distinct_id] = true;
987 while (!q.empty()) {
988 auto [cur_distinct, parent] = q.front();
989 q.pop();
990
991 std::set<int> neigh_distinct;
992 for (int idx : distinct_constraints_[cur_distinct])
993 for (int nxt_distinct :
994 distinct_containing_comp_idx[comp_id[idx]]) {
995 if (nxt_distinct == cur_distinct or
996 nxt_distinct == parent)
997 continue;
998
999 // Cycle found.
1000 if (vis_distinct[nxt_distinct])
1001 throw _detail::error("failed to generate sequence: "
1002 "complex constraints");
1003
1004 neigh_distinct.insert(nxt_distinct);
1005 }
1006
1007 for (int nxt_distinct : neigh_distinct) {
1008 vis_distinct[nxt_distinct] = true;
1009 q.emplace(nxt_distinct, cur_distinct);
1010
1011 // Generates this distinct constraint.
1012 std::set<T> nxt_defined_values;
1013 for (int idx2 : distinct_constraints_[nxt_distinct])
1014 if (defined_idx[idx2]) {
1015 // There can not be any more defined. This case is
1016 // when there are values not coverered by a single
1017 // distinct constraint in the tree.
1018 if (initially_defined_comp_idx[comp_id[idx2]])
1019 throw _detail::error(
1020 "failed to generate sequence: "
1021 "complex constraints");
1022
1023 nxt_defined_values.insert(vec[idx2]);
1024 }
1025 int new_value_count =
1026 distinct_constraints_[nxt_distinct].size() -
1027 static_cast<int>(nxt_defined_values.size());
1028 std::vector<T> generated_values = generate_distinct_values(
1029 new_value_count, nxt_defined_values);
1030 auto val_it = generated_values.begin();
1031 for (int idx2 : distinct_constraints_[nxt_distinct])
1032 if (!defined_idx[idx2]) {
1033 define_comp(comp_id[idx2], *val_it);
1034 ++val_it;
1035 }
1036 }
1037 }
1038 };
1039
1040 // Loops through distinct constraints, sorts distinct constraints
1041 // by number of defined components (non-increasing). This guarantees
1042 // that if there is a valid root (that covers all 'defined'), we find
1043 // it.
1044 {
1045 std::vector<std::pair<int, int>> defined_cnt_and_distinct_idx;
1046 int dist_id = 0;
1047 for (const std::set<int> &distinct : distinct_constraints_) {
1048 int defined_cnt = 0;
1049 for (int idx : distinct)
1050 if (defined_idx[idx]) {
1051 ++defined_cnt;
1052 initially_defined_comp_idx[comp_id[idx]] = true;
1053 }
1054 defined_cnt_and_distinct_idx.emplace_back(defined_cnt, dist_id);
1055 ++dist_id;
1056 }
1057
1058 std::sort(defined_cnt_and_distinct_idx.rbegin(),
1059 defined_cnt_and_distinct_idx.rend());
1060 for (auto [defined_cnt, distinct_idx] :
1061 defined_cnt_and_distinct_idx)
1062 if (!vis_distinct[distinct_idx])
1063 define_tree(distinct_idx);
1064 }
1065
1066 // Loops through distinct constraints do define the rest.
1067 for (std::size_t dist_id = 0; dist_id < distinct_constraints_.size();
1068 ++dist_id)
1069 if (!vis_distinct[dist_id])
1070 define_tree(dist_id);
1071
1072 // Define final values. These values all should be random in [l, r], and
1073 // the distinct constraints have already been processed. However, there
1074 // can be still equality constraints, so we set entire components.
1075 for (int idx = 0; idx < size_; ++idx)
1076 if (!defined_idx[idx])
1077 define_comp(comp_id[idx], next<T>(value_l_, value_r_));
1078
1079 if (!values_.empty()) {
1080 // Needs to fetch the values from the value set.
1081 std::vector<T> value_vec(values_.begin(), values_.end());
1082 for (T &val : vec)
1083 val = value_vec[val];
1084 }
1085
1086 return instance(vec);
1087 }
1088};
1089
1090/*******************
1091 * *
1092 * PERMUTATION *
1093 * *
1094 *******************/
1095
1096/*
1097 * Permutation generation.
1098 *
1099 * Permutation are defined always as numbers in [0, n), that is, 0-based.
1100 */
1101
1103 int size_; // Size of permutation.
1104 std::vector<std::pair<int, int>> sets; // {idx, value}.
1105
1106 // Creates generator for permutation of size 'size'.
1107 permutation(int size) : size_(size) {
1108 tgen_ensure(size_ > 0, "size must be positive");
1109 }
1110
1111 // Restricts sequences for permutation[idx] = value.
1112 permutation &set(int idx, int value) {
1113 tgen_ensure(0 <= idx and idx < size_, "index must be valid");
1114 sets.emplace_back(idx, value);
1115 return *this;
1116 }
1117
1118 // Permutation instance.
1119 // Operations on an instance are not random.
1120 struct instance {
1121 using _tgen_instance_tag = _detail::generator_instance_tag;
1122 using std_type = std::vector<int>; // std type for instance.
1123 std::vector<int> vec_; // Permutation.
1124 bool add_1_; // If should add 1, for printing.
1125
1126 instance(const std::vector<int> &vec) : vec_(vec), add_1_(false) {
1127 tgen_ensure(!vec_.empty(), "permutation cannot be empty");
1128 std::vector<bool> vis(vec_.size(), false);
1129 for (int i = 0; i < size(); ++i) {
1130 tgen_ensure(0 <= vec_[i] and
1131 vec_[i] < static_cast<int>(vec_.size()),
1132 "permutation values must be from `0` to `size-1`");
1133 tgen_ensure(!vis[vec_[i]],
1134 "cannot have repeated values in permutation");
1135 vis[vec_[i]] = true;
1136 }
1137 }
1138 instance(const std::initializer_list<int> &il)
1139 : instance(std::vector<int>(il.begin(), il.end())) {}
1140
1141 // Fetches size.
1142 int size() const { return vec_.size(); }
1143
1144 // Fetches position idx.
1145 int &operator[](int idx) { return vec_[idx]; }
1146 const int &operator[](int idx) const { return vec_[idx]; }
1147
1148 // Returns parity of the permutation (+1 if even, -1 if odd).
1149 // O(n).
1150 int parity() const {
1151 std::vector<bool> vis(size(), false);
1152 int cycles = 0;
1153
1154 for (int i = 0; i < size(); ++i)
1155 if (!vis[i]) {
1156 cycles++;
1157 for (int j = i; !vis[j]; j = vec_[j])
1158 vis[j] = true;
1159 }
1160 // Even iff (n - cycles) is even.
1161 return ((size() - cycles) % 2 == 0) ? +1 : -1;
1162 }
1163
1164 // Sorts values in increasign order.
1165 // O(n).
1167 for (int i = 0; i < size(); ++i)
1168 vec_[i] = i;
1169 return *this;
1170 }
1171
1172 // Reverses permutation.
1173 // O(n).
1175 std::reverse(vec_.begin(), vec_.end());
1176 return *this;
1177 }
1178
1179 // Inverse of the permutation.
1180 // O(n).
1182 std::vector<int> inv(size());
1183 for (int i = 0; i < size(); ++i)
1184 inv[vec_[i]] = i;
1185 swap(vec_, inv);
1186 return *this;
1187 }
1188
1189 // Sets that should print values 1-based.
1190 // O(1).
1192 add_1_ = true;
1193 return *this;
1194 }
1195
1196 // Prints to std::ostream, separated by spaces.
1197 friend std::ostream &operator<<(std::ostream &out,
1198 const instance &inst) {
1199 for (int i = 0; i < inst.size(); ++i) {
1200 if (i > 0)
1201 out << ' ';
1202 out << inst[i] + inst.add_1_;
1203 }
1204 return out;
1205 }
1206
1207 // Gets a std::vector representing the instance.
1208 std::vector<int> to_std() const { return vec_; }
1209 };
1210
1211 // Generates permutation instance.
1212 // O(n).
1213 instance gen() const {
1214 std::vector<int> idx_to_val(size_, -1), val_to_idx(size_, -1);
1215 for (auto [idx, val] : sets) {
1216 tgen_ensure(0 <= val and val < size_,
1217 "value in permutation must be in [0, " +
1218 std::to_string(size_) + ")");
1219
1220 if (idx_to_val[idx] != -1) {
1221 tgen_ensure(idx_to_val[idx] == val,
1222 "cannot set an idex to two different values");
1223 } else
1224 idx_to_val[idx] = val;
1225
1226 if (val_to_idx[val] != -1) {
1227 tgen_ensure(val_to_idx[val] == idx,
1228 "cannot set two indices to the same value");
1229 } else
1230 val_to_idx[val] = idx;
1231 }
1232
1233 std::vector<int> perm(size_);
1234 std::iota(perm.begin(), perm.end(), 0);
1235 shuffle(perm.begin(), perm.end());
1236 int cur_idx = 0;
1237 for (int &i : idx_to_val)
1238 if (i == -1) {
1239 // While this value is used, skip.
1240 while (val_to_idx[perm[cur_idx]] != -1)
1241 ++cur_idx;
1242 i = perm[cur_idx++];
1243 }
1244 return idx_to_val;
1245 }
1246
1247 // Generates permutation instance, given cycle sizes.
1248 // O(n).
1249 instance gen(std::vector<int> cycle_sizes) const {
1251 size_ == std::accumulate(cycle_sizes.begin(), cycle_sizes.end(), 0),
1252 "cycle sizes must add up to size of permutation");
1253
1254 // Creates cycles.
1255 std::vector<int> order(size_);
1256 std::iota(order.begin(), order.end(), 0);
1257 shuffle(order.begin(), order.end());
1258 int idx = 0;
1259 std::vector<std::vector<int>> cycles;
1260 for (int cycle_size : cycle_sizes) {
1261 cycles.emplace_back();
1262 for (int i = 0; i < cycle_size; ++i)
1263 cycles.back().push_back(order[idx++]);
1264 }
1265
1266 // Retrieves permutation from cycles.
1267 std::vector<int> perm(size_, -1);
1268 for (const std::vector<int> &cycle : cycles) {
1269 int cur_size = cycle.size();
1270 for (int i = 0; i < cur_size; ++i)
1271 perm[cycle[i]] = cycle[(i + 1) % cur_size];
1272 }
1273
1274 return instance(perm);
1275 }
1276};
1277
1278/************
1279 * *
1280 * MATH *
1281 * *
1282 ************/
1283
1284namespace math {
1285namespace _detail {
1286
1287inline int ctzll(uint64_t x) {
1288 // Mistery code found on the internet.
1289 // Uses de Brujin sequence.
1290 static const unsigned char index64[64] = {
1291 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
1292 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
1293 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
1294 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12};
1295 return index64[((x & -x) * 0x022FDD63CC95386D) >> 58];
1296}
1297
1298inline uint64_t mul_mod(uint64_t a, uint64_t b, uint64_t m) {
1299 return static_cast<unsigned __int128>(a) * b % m;
1300}
1301
1302// O(log n).
1303// 0 <= x < m.
1304inline uint64_t expo_mod(uint64_t x, uint64_t y, uint64_t m) {
1305 if (!y)
1306 return 1;
1307 uint64_t ans = expo_mod(mul_mod(x, x, m), y / 2, m);
1308 return y % 2 ? mul_mod(x, ans, m) : ans;
1309}
1310
1311} // namespace _detail
1312
1313// O(log^2 n).
1314inline bool is_prime(uint64_t n) {
1315 if (n < 2)
1316 return false;
1317 if (n == 2 or n == 3)
1318 return true;
1319 if (n % 2 == 0)
1320 return false;
1321
1322 uint64_t r = _detail::ctzll(n - 1), d = n >> r;
1323 // These bases are guaranteed to work for n <= 2^64.
1324 for (int a : {2, 325, 9375, 28178, 450775, 9780504, 1795265022}) {
1325 uint64_t x = _detail::expo_mod(a, d, n);
1326 if (x == 1 or x == n - 1 or a % n == 0)
1327 continue;
1328
1329 for (uint64_t j = 0; j < r - 1; ++j) {
1330 x = _detail::mul_mod(x, x, n);
1331 if (x == n - 1)
1332 break;
1333 }
1334 if (x != n - 1)
1335 return false;
1336 }
1337 return true;
1338}
1339
1340namespace _detail {
1341
1342inline uint64_t pollard_rho(uint64_t n) {
1343 if (n == 1 or is_prime(n))
1344 return n;
1345 auto f = [n](uint64_t x) { return mul_mod(x, x, n) + 1; };
1346
1347 uint64_t x = 0, y = 0, t = 30, prd = 2, x0 = 1, q;
1348 while (t % 40 != 0 or std::gcd(prd, n) == 1) {
1349 if (x == y)
1350 x = ++x0, y = f(x);
1351 q = mul_mod(prd, x > y ? x - y : y - x, n);
1352 if (q != 0)
1353 prd = q;
1354 x = f(x), y = f(f(y)), t++;
1355 }
1356 return std::gcd(prd, n);
1357}
1358
1359inline std::vector<uint64_t> factor(uint64_t n) {
1360 if (n == 1)
1361 return {};
1362 if (is_prime(n))
1363 return {n};
1364 uint64_t d = _detail::pollard_rho(n);
1365 std::vector<uint64_t> l = factor(d), r = factor(n / d);
1366 l.insert(l.end(), r.begin(), r.end());
1367 return l;
1368}
1369
1370} // namespace _detail
1371
1372// Sorted.
1373// O(n^(1/4) log n) expected.
1374// 0 < n.
1375inline std::vector<uint64_t> factor(uint64_t n) {
1376 tgen_ensure(n > 0, "number to factor must be positive");
1377 auto factors = _detail::factor(n);
1378 std::sort(factors.begin(), factors.end());
1379 return factors;
1380}
1381
1382// Sorted.
1383// O(n^(1/4) log n) expected.
1384// 0 < n.
1385inline std::vector<std::pair<uint64_t, int>> factor_by_prime(uint64_t n) {
1386 tgen_ensure(n > 0, "number to factor must be positive");
1387 std::vector<std::pair<uint64_t, int>> primes;
1388 for (uint64_t p : factor(n)) {
1389 if (!primes.empty() and primes.back().first == p)
1390 ++primes.back().second;
1391 else
1392 primes.emplace_back(p, 1);
1393 }
1394 return primes;
1395}
1396
1397namespace _detail {
1398
1399// O(log mod).
1400// 0 < a < mod.
1401// gcd(a, mod) = 1.
1402inline __int128 modular_inverse_128(__int128 a, __int128 mod) {
1403 tgen_ensure(0 < a and a < mod,
1404 "remainder must be positive and smaller than the mod");
1405
1406 __int128 t = 0, new_t = 1;
1407 __int128 r = mod, new_r = a;
1408
1409 while (new_r != 0) {
1410 __int128 q = r / new_r;
1411
1412 auto tmp_t = t - q * new_t;
1413 t = new_t;
1414 new_t = tmp_t;
1415
1416 auto tmp_r = r - q * new_r;
1417 r = new_r;
1418 new_r = tmp_r;
1419 }
1420
1421 tgen_ensure(r == 1, "remainder and mod must be coprime");
1422
1423 if (t < 0)
1424 t += mod;
1425 return t;
1426}
1427
1428} // namespace _detail
1429
1430// O(log mod).
1431// 0 < a < mod.
1432// gcd(a, mod) = 1.
1433inline uint64_t modular_inverse(uint64_t a, uint64_t mod) {
1434 return _detail::modular_inverse_128(a, mod);
1435}
1436
1437// O(n^(1/4) log n) expected.
1438// 0 < n.
1439inline uint64_t totient(uint64_t n) {
1440 tgen_ensure(n > 0, "totient(0) is undefined");
1441 uint64_t phi = n;
1442
1443 for (auto [p, e] : factor_by_prime(n))
1444 phi -= phi / p;
1445
1446 return phi;
1447}
1448
1449// Returns `(p_i, g_i)`: `p_i` is the prime, `g_i` is the gap.
1450inline const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> &
1451prime_gaps() {
1452 // From https://en.wikipedia.org/wiki/Prime_gap.
1453 static const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> value{
1454 /* clang-format off */ {
1455 2, 3, 7, 23, 89, 113, 523, 887, 1129, 1327, 9551, 15683, 19609,
1456 31397, 155921, 360653, 370261, 492113, 1349533, 1357201, 2010733,
1457 4652353, 17051707, 20831323, 47326693, 122164747, 189695659,
1458 191912783, 387096133, 436273009, 1294268491, 1453168141,
1459 2300942549, 3842610773, 4302407359, 10726904659, 20678048297,
1460 22367084959, 25056082087, 42652618343, 127976334671, 182226896239,
1461 241160624143, 297501075799, 303371455241, 304599508537,
1462 416608695821, 461690510011, 614487453523, 738832927927,
1463 1346294310749, 1408695493609, 1968188556461, 2614941710599,
1464 7177162611713, 13829048559701, 19581334192423, 42842283925351,
1465 90874329411493, 171231342420521, 218209405436543, 1189459969825483,
1466 1686994940955803, 1693182318746371, 43841547845541059,
1467 55350776431903243, 80873624627234849, 203986478517455989,
1468 218034721194214273, 305405826521087869, 352521223451364323,
1469 401429925999153707, 418032645936712127, 804212830686677669,
1470 1425172824437699411, 5733241593241196731, 6787988999657777797
1471 }, /* clang-format on */
1472 {1, 2, 4, 6, 8, 14, 18, 20, 22, 34, 36,
1473 44, 52, 72, 86, 96, 112, 114, 118, 132, 148, 154,
1474 180, 210, 220, 222, 234, 248, 250, 282, 288, 292, 320,
1475 336, 354, 382, 384, 394, 456, 464, 468, 474, 486, 490,
1476 500, 514, 516, 532, 534, 540, 582, 588, 602, 652, 674,
1477 716, 766, 778, 804, 806, 906, 916, 924, 1132, 1184, 1198,
1478 1220, 1224, 1248, 1272, 1328, 1356, 1370, 1442, 1476, 1488, 1510}};
1479
1480 return value;
1481}
1482
1483// Returns pair (first_composite_in_gap, last_composite_in_gap).
1484// O(log r) approximately.
1485inline std::pair<uint64_t, uint64_t> prime_gap_upto(uint64_t r) {
1486 if (r < 4)
1487 throw tgen::_detail::there_is_no_upto_error("prime gap", r);
1488
1489 const auto &[P, G] = prime_gaps();
1490 for (int i = P.size() - 1;; --i) {
1491 if (P[i] >= r)
1492 continue;
1493
1494 uint64_t right = std::min(r, P[i] + G[i] - 1);
1495 uint64_t prev = i > 0 ? G[i - 1] : 0;
1496 uint64_t curr = right - P[i];
1497
1498 if (curr >= prev)
1499 return {P[i] + 1, right};
1500 }
1501}
1502
1503// From https://oeis.org/A002182/b002182.txt.
1505 /* clang-format off */
1506 static const std::vector<uint64_t> highly_composites = {
1507 1, 2, 4, 6, 12, 24, 36, 48, 60, 120, 180, 240, 360, 720, 840, 1260, 1680,
1508 2520, 5040, 7560, 10080, 15120, 20160, 25200, 27720, 45360, 50400, 55440,
1509 83160, 110880, 166320, 221760, 277200, 332640, 498960, 554400, 665280,
1510 720720, 1081080, 1441440, 2162160, 2882880, 3603600, 4324320, 6486480,
1511 7207200, 8648640, 10810800, 14414400, 17297280, 21621600, 32432400,
1512 36756720, 43243200, 61261200, 73513440, 110270160, 122522400, 147026880,
1513 183783600, 245044800, 294053760, 367567200, 551350800, 698377680, 735134400,
1514 1102701600, 1396755360, 2095133040, 2205403200, 2327925600, 2793510720,
1515 3491888400, 4655851200, 5587021440, 6983776800, 10475665200, 13967553600,
1516 20951330400, 27935107200, 41902660800, 48886437600, 64250746560,
1517 73329656400, 80313433200, 97772875200, 128501493120, 146659312800,
1518 160626866400, 240940299600, 293318625600, 321253732800, 481880599200,
1519 642507465600, 963761198400, 1124388064800, 1606268664000, 1686582097200,
1520 1927522396800, 2248776129600, 3212537328000, 3373164194400, 4497552259200,
1521 6746328388800, 8995104518400, 9316358251200, 13492656777600, 18632716502400,
1522 26985313555200, 27949074753600, 32607253879200, 46581791256000,
1523 48910880818800, 55898149507200, 65214507758400, 93163582512000,
1524 97821761637600, 130429015516800, 195643523275200, 260858031033600,
1525 288807105787200, 391287046550400, 577614211574400, 782574093100800,
1526 866421317361600, 1010824870255200, 1444035528936000, 1516237305382800,
1527 1732842634723200, 2021649740510400, 2888071057872000, 3032474610765600,
1528 4043299481020800, 6064949221531200, 8086598962041600, 10108248702552000,
1529 12129898443062400, 18194847664593600, 20216497405104000, 24259796886124800,
1530 30324746107656000, 36389695329187200, 48519593772249600, 60649492215312000,
1531 72779390658374400, 74801040398884800, 106858629141264000,
1532 112201560598327200, 149602080797769600, 224403121196654400,
1533 299204161595539200, 374005201994424000, 448806242393308800,
1534 673209363589963200, 748010403988848000, 897612484786617600,
1535 1122015605983272000, 1346418727179926400, 1795224969573235200,
1536 2244031211966544000, 2692837454359852800, 3066842656354276800,
1537 4381203794791824000, 4488062423933088000, 6133685312708553600,
1538 8976124847866176000, 9200527969062830400, 12267370625417107200ULL,
1539 15334213281771384000ULL, 18401055938125660800ULL}; /* clang-format on */
1540 return highly_composites;
1541}
1542
1543// O(log r) approximately.
1544inline uint64_t highly_composite_upto(uint64_t r) {
1545 for (int i = highly_composites().size() - 1; i >= 0; --i)
1546 if (highly_composites()[i] <= r)
1547 return highly_composites()[i];
1548
1549 throw tgen::_detail::there_is_no_upto_error("highly composite number", r);
1550}
1551
1552// O(log r) expected.
1553// Generates a random prime in [l, r].
1554inline uint64_t gen_prime(uint64_t l, uint64_t r) {
1555 if (r < l or r < 2)
1556 throw tgen::_detail::there_is_no_in_range_error("prime", l, r);
1557 l = std::max<uint64_t>(l, 2);
1558 // There might be no primes in the range.
1559 if (r - l <= prime_gaps().second.back()) {
1560 std::vector<uint64_t> vals(r - l + 1);
1561 iota(vals.begin(), vals.end(), l);
1562 shuffle(vals.begin(), vals.end());
1563 for (uint64_t i : vals)
1564 if (is_prime(i))
1565 return i;
1566 throw tgen::_detail::there_is_no_in_range_error("prime", l, r);
1567 }
1568
1569 uint64_t n;
1570 do {
1571 n = next(l, r);
1572 } while (!is_prime(n));
1573 return n;
1574}
1575
1576// O(log^3 l) expected.
1577// l <= 2^64 - 59.
1578inline uint64_t prime_from(uint64_t l) {
1579 tgen_ensure(l <= std::numeric_limits<uint64_t>::max() - 58,
1580 "invalid bound");
1581 for (uint64_t i = std::max<uint64_t>(2, l);; ++i)
1582 if (is_prime(i))
1583 return i;
1584}
1585
1586// O(log^3 r) expected.
1587inline uint64_t prime_upto(uint64_t r) {
1588 if (r >= 2)
1589 for (uint64_t i = r; i >= 2; --i)
1590 if (is_prime(i))
1591 return i;
1592 throw tgen::_detail::there_is_no_upto_error("prime", r);
1593}
1594
1595// checks if a * b <= limit, for positive numbers.
1596inline bool mul_leq(uint64_t a, uint64_t b, uint64_t limit) {
1597 if (a == 0)
1598 return true;
1599 return a <= limit / b;
1600}
1601
1602// base^exp, or null if base^exp > limit.
1603inline std::optional<uint64_t> expo(uint64_t base, uint64_t exp,
1604 uint64_t limit) {
1605 uint64_t result = 1;
1606
1607 while (exp) {
1608 if (exp & 1) {
1609 if (!mul_leq(result, base, limit))
1610 return std::nullopt;
1611 result *= base;
1612 }
1613
1614 exp >>= 1;
1615 // Necesary for correctness.
1616 if (!exp)
1617 break;
1618
1619 if (!mul_leq(base, base, limit))
1620 return std::nullopt;
1621 base *= base;
1622 }
1623 return result;
1624}
1625
1626// O(log n log k).
1627// 0 <= n.
1628// 0 < k.
1629inline uint64_t kth_root_floor(uint64_t n, uint64_t k) {
1630 tgen_ensure(k > 0 and n >= 0, "values must be valid");
1631 if (k == 1 or n <= 1)
1632 return n;
1633
1634 uint64_t lo = 1, hi = 1ULL << ((64 + k - 1) / k);
1635
1636 while (lo < hi) {
1637 uint64_t mid = lo + (hi - lo + 1) / 2;
1638
1639 if (expo(mid, k, n)) {
1640 lo = mid;
1641 } else {
1642 hi = mid - 1;
1643 }
1644 }
1645 return lo;
1646}
1647
1648// O(n^(1/4) log n) expected.
1649// 0 < n.
1650inline int num_divisors(uint64_t n) {
1651 int divisors = 1;
1652 for (auto [p, e] : factor_by_prime(n))
1653 divisors *= (e + 1);
1654 return divisors;
1655}
1656
1657// O(log(r) log(divisor_count)).
1658// divisor_count is prime.
1659inline uint64_t gen_divisor_count(uint64_t l, uint64_t r, int divisor_count) {
1660 tgen_ensure(divisor_count > 0 and is_prime(divisor_count),
1661 "divisor count must be prime");
1662 int root = divisor_count - 1;
1663 uint64_t p = gen_prime(kth_root_floor(l, root), kth_root_floor(r, root));
1664 return *expo(p, root, r);
1665}
1666
1667namespace _detail {
1668
1669// gcd(a, b).
1670// O(log a).
1671inline __int128 gcd128(__int128 a, __int128 b) {
1672 if (a < 0)
1673 a = -a;
1674 if (b < 0)
1675 b = -b;
1676 while (b != 0) {
1677 __int128 t = a % b;
1678 a = b;
1679 b = t;
1680 }
1681 return a;
1682}
1683
1684// min(2^64, a*b).
1685// O(log a).
1686// a, b >= 0.
1687inline __int128 mul_saturate(__int128 a, __int128 b) {
1688 tgen_ensure(a >= 0 and b >= 0);
1689 static const __int128 LIMIT = (__int128)1 << 64;
1690 if (a == 0 or b == 0)
1691 return 0;
1692 if (a > LIMIT / b)
1693 return LIMIT;
1694 return a * b;
1695}
1696
1697struct crt {
1698 using T = __int128;
1699 T a, m;
1700
1701 crt() : a(0), m(1) {}
1702 crt(T a_, T m_) : a(a_), m(m_) {}
1703 crt operator*(crt C) {
1704 if (m == 0 or C.m == 0)
1705 return {-1, 0};
1706
1707 T g = gcd128(m, C.m);
1708 if ((C.a - a) % g != 0)
1709 return {-1, 0};
1710
1711 T m1 = m / g;
1712 T m2 = C.m / g;
1713
1714 if (m2 == 1)
1715 return {a, m};
1716
1717 T inv = modular_inverse_128(m1 % m2, m2);
1718
1719 T k = ((C.a - a) / g) % m2;
1720 if (k < 0)
1721 k += m2;
1722
1723 k = static_cast<unsigned __int128>(k) * inv % m2;
1724
1725 T lcm = mul_saturate(m, m2);
1726
1727 T res = (a + static_cast<T>((static_cast<unsigned __int128>(k) * m) %
1728 lcm)) %
1729 lcm;
1730 if (res < 0)
1731 res += lcm;
1732
1733 return {res, lcm};
1734 }
1735};
1736
1737} // namespace _detail
1738
1739// O(|mods| + log r).
1740// |rems| = |mods|.
1741// rems_i < mods_i.
1742inline uint64_t gen_congruent(uint64_t l, uint64_t r,
1743 std::vector<uint64_t> rems,
1744 std::vector<uint64_t> mods) {
1745 if (l > r)
1746 throw tgen::_detail::there_is_no_in_range_error("congruent number", l,
1747 r);
1748 tgen_ensure(rems.size() == mods.size(),
1749 "number of remainders and mods must be the same");
1750
1751 _detail::crt crt;
1752 for (int i = 0; i < static_cast<int>(rems.size()); ++i) {
1753 tgen_ensure(rems[i] < mods[i],
1754 "remainder must be smaller than the mod");
1755 crt = crt * _detail::crt(rems[i], mods[i]);
1756
1757 if (crt.a == -1 or crt.m > r) {
1758 if (!(l <= crt.a and crt.a <= r))
1759 throw tgen::_detail::there_is_no_in_range_error(
1760 "congruent number", l, r);
1761
1762 bool valid_candidate = true;
1763 for (int j = 0; j < static_cast<int>(rems.size()); ++j)
1764 if (crt.a % mods[j] != rems[j])
1765 valid_candidate = false;
1766 if (valid_candidate)
1767 return crt.a;
1768 throw tgen::_detail::there_is_no_in_range_error("congruent number",
1769 l, r);
1770 }
1771 }
1772
1773 uint64_t k_min = crt.a >= l ? 0 : ((l - crt.a) + crt.m - 1) / crt.m;
1774 uint64_t k_max = (r - crt.a) / crt.m;
1775
1776 if (k_min > k_max)
1777 throw tgen::_detail::there_is_no_in_range_error("congruent number", l,
1778 r);
1779
1780 return crt.a + next(k_min, k_max) * crt.m;
1781}
1782
1783// O(1).
1784// rem < mod.
1785inline uint64_t gen_congruent(uint64_t l, uint64_t r, uint64_t rem,
1786 uint64_t mod) {
1787 return gen_congruent(l, r, std::vector<uint64_t>({rem}),
1788 std::vector<uint64_t>({mod}));
1789}
1790
1791// O(log r).
1792inline uint64_t gen_even(uint64_t l, uint64_t r) {
1793 return gen_congruent(l, r, 0, 2);
1794}
1795
1796// O(log r).
1797inline uint64_t gen_odd(uint64_t l, uint64_t r) {
1798 return gen_congruent(l, r, 1, 2);
1799}
1800
1801// Mod used for FFT/NTT.
1802inline constexpr int FFT_MOD = 998244353;
1803
1804// Fibonacci sequence up to 2^64.
1805inline const std::vector<uint64_t> &fibonacci() {
1806 static const std::vector<uint64_t> fib = [] {
1807 std::vector<uint64_t> v = {0, 1};
1808 while (v.back() <=
1809 std::numeric_limits<uint64_t>::max() - v[v.size() - 2])
1810 v.push_back(v.back() + v[v.size() - 2]);
1811 return v;
1812 }();
1813 return fib;
1814}
1815
1816namespace _detail {
1817
1818inline constexpr long double LOG_ZERO = -INFINITY;
1819inline constexpr long double LOG_ONE = 0.0;
1820
1821inline long double log_space(long double x) {
1822 return x == 0.0 ? LOG_ZERO : std::log(x);
1823}
1824
1825// Math hack to add two values in log space.
1826inline long double add_log_space(long double a, long double b) {
1827 if (a == LOG_ZERO)
1828 return b;
1829 if (b == LOG_ZERO)
1830 return a;
1831 if (a < b)
1832 std::swap(a, b);
1833 if (b == LOG_ZERO)
1834 return a;
1835 return a + log1p(exp(b - a));
1836}
1837
1838// Math hack to subtract two values in log space.
1839// a >= b.
1840inline long double sub_log_space(long double a, long double b) {
1841 if (b >= a)
1842 return LOG_ZERO;
1843 if (b == LOG_ZERO)
1844 return a;
1845 return a + log1p(-exp(b - a));
1846}
1847
1848} // namespace _detail
1849
1850// Parition is ordered (composition), that is, (1, 1, 2) != (1, 2, 1).
1851// O(n).
1852// 0 < n.
1853// 0 < part_l.
1854inline std::vector<int> gen_partition(int n, int part_l = 1, int part_r = -1) {
1855 if (part_r == -1)
1856 part_r = n;
1857 part_r = std::min(part_r, n);
1858 tgen_ensure(n > 0 and part_l > 0, "invalid parameters to gen_partition");
1859 tgen_ensure(part_l <= n and part_r > 0, "no such partition");
1860
1861 // dp[i] = log(numbers of ways to add to i).
1862 std::vector<long double> dp(n + 1, _detail::LOG_ZERO);
1863 dp[0] = _detail::LOG_ONE;
1864 long double window = _detail::LOG_ZERO;
1865 for (int i = 1; i <= n; ++i) {
1866 if (i >= part_l)
1867 window = _detail::add_log_space(window, dp[i - part_l]);
1868 if (i >= part_r + 1)
1869 window = _detail::sub_log_space(window, dp[i - part_r - 1]);
1870 dp[i] = window;
1871 }
1872 tgen_ensure(dp[n] >= 0, "no such partition");
1873
1874 // Crazy math tricks ahead.
1875 auto dp_pref = dp;
1876 for (int i = 1; i <= n; ++i)
1877 dp_pref[i] = _detail::add_log_space(dp_pref[i - 1], dp[i]);
1878
1879 std::vector<int> part;
1880 int sum = n;
1881 while (sum > 0) {
1882 // Will generate a number such that what remains is in [l, r].
1883 int l = std::max(0, sum - part_r), r = sum - part_l;
1884 tgen::_detail::tgen_ensure_against_bug(r >= 0);
1885
1886 int nxt_sum = std::min(sum, r);
1887 long double random = next<long double>(0, 1);
1888
1889 // We generate a value X (log space), and then choose nxt_sum such that
1890 // dp_pref[nxt_sum-1] < X <= dp_pref[nxt_sum].
1891
1892 // Math hack:
1893 // Let A = pref[l-1], B = pref[r], U = rand().
1894 // X = log[exp(A) + U * (exp(B) - exp(A))]
1895 // = log{exp(B) * [exp(A) / exp(B) + U * (1 - exp(A) / exp(B))]}
1896 // = B + log[exp(A - B) + U - U * exp(A - B))]
1897 // = B + log[U + (1 - U) * exp(A - B)].
1898 long double val_l = l ? dp_pref[l - 1] : _detail::LOG_ZERO,
1899 val_r = dp_pref[r];
1900 while (nxt_sum > l and
1901 dp_pref[nxt_sum - 1] >=
1902 val_r + _detail::log_space(random + (1 - random) *
1903 exp(val_l - val_r)))
1904 --nxt_sum;
1905
1906 part.push_back(sum - nxt_sum);
1907 sum = nxt_sum;
1908 }
1909
1910 return part;
1911}
1912
1913// Parition is ordered (composition), that is, (1, 1, 2) != (1, 2, 1).
1914// O(n) time/memory if part_r = -1, O(n * k) time/memory otherwise.
1915// 0 < k <= n.
1916// 0 <= part_l.
1917inline std::vector<int> gen_partition_fixed_size(int n, int k, int part_l = 0,
1918 int part_r = -1) {
1919 if (part_r == -1)
1920 part_r = n;
1921 part_r = std::min(part_r, n);
1922 tgen_ensure(0 < k and k <= n and part_l >= 0,
1923 "invalid parameters to gen_partition_fixed_size");
1924 tgen_ensure(static_cast<long long>(k) * part_l <= n and
1925 n <= static_cast<long long>(k) * part_r,
1926 "no such partition");
1927
1928 // What we need to distribute to the parts.
1929 int s = n - k * part_l;
1930
1931 std::vector<int> part(k);
1932 if (part_r == n) {
1933 // Stars and bars - O(n).
1934 std::vector<int> cuts = {-1};
1935
1936 int total = s + k - 1, bars = k - 1;
1937 for (int i = 0; i < total and bars > 0; ++i)
1938 if (next<long double>(0, 1) <
1939 static_cast<long double>(bars) / (total - i)) {
1940 cuts.push_back(i);
1941 --bars;
1942 }
1943 cuts.push_back(total);
1944
1945 // Recovers parts.
1946 for (int i = 0; i < k; ++i)
1947 part[i] = cuts[i + 1] - cuts[i] - 1;
1948 } else {
1949 // DP with log trick - O(nk).
1950 int u = part_r - part_l;
1951
1952 // dp[i][j] = log(#ways to fill i parts with sum j)
1953 std::vector<std::vector<long double>> dp(
1954 k + 1, std::vector<long double>(s + 1, _detail::LOG_ZERO));
1955 dp[0][0] = _detail::LOG_ONE;
1956
1957 for (int i = 1; i <= k; ++i) {
1958 std::vector<long double> pref = dp[i - 1];
1959 for (int j = 1; j <= s; ++j)
1960 pref[j] = _detail::add_log_space(pref[j - 1], dp[i - 1][j]);
1961
1962 for (int j = 0; j <= s; ++j) {
1963 dp[i][j] = pref[j];
1964 if (j >= u + 1)
1965 dp[i][j] =
1966 _detail::sub_log_space(dp[i][j], pref[j - u - 1]);
1967 }
1968 }
1969
1970 // Recovers parts backwards.
1971 int left_to_distribute = s;
1972 for (int i = k; i >= 1; --i) {
1973 long double log_total = _detail::LOG_ZERO;
1974 for (int j = 0; j <= u and j <= left_to_distribute; ++j)
1975 log_total = _detail::add_log_space(
1976 log_total, dp[i - 1][left_to_distribute - j]);
1977 tgen::_detail::tgen_ensure_against_bug(log_total !=
1978 _detail::LOG_ZERO);
1979
1980 // Now we choose a number with probability proportional to
1981 // dp[i-1][.].
1982
1983 // log(rand() * total) = log(rand()) + log(total).
1984 long double random =
1985 _detail::log_space(next<long double>(0, 1)) + log_total;
1986
1987 long double cur_prob = _detail::LOG_ZERO;
1988 int chosen = 0;
1989 for (int j = 0; j <= u and j <= left_to_distribute; ++j) {
1990 cur_prob = _detail::add_log_space(
1991 cur_prob, dp[i - 1][left_to_distribute - j]);
1992 if (random < cur_prob) {
1993 chosen = j;
1994 break;
1995 }
1996 }
1997
1998 part[k - i] = chosen;
1999 left_to_distribute -= chosen;
2000 }
2001 }
2002
2003 for (int &i : part)
2004 i += part_l;
2005 return part;
2006}
2007
2008}; // namespace math
2009
2010}; // namespace tgen
C::value_type any(const C &container)
Choses a random element from container.
Definition tgen.h:370
C shuffled(const C &container)
Shuffles a container.
Definition tgen.h:330
void shuffle(It first, It last)
Shuffles range inplace, for random_access_iterator.
Definition tgen.h:316
It::value_type any(It first, It last)
Choses a random element from iterator range.
Definition tgen.h:359
T next(T l, T r)
Returns a random number in [l, r].
Definition tgen.h:302
#define tgen_ensure(cond,...)
Ensures condition is true.
Definition tgen.h:87
C choose(int k, const C &container)
Chooses elements from container, as in a subsequence fixed length.
Definition tgen.h:390
std::pair< uint64_t, uint64_t > prime_gap_upto(uint64_t r)
Largest prime gap up to given number.
Definition tgen.h:1485
uint64_t gen_odd(uint64_t l, uint64_t r)
Generates random odd number in a given range.
Definition tgen.h:1797
uint64_t prime_upto(uint64_t r)
Computes largest prime up to given value.
Definition tgen.h:1587
std::vector< int > gen_partition(int n, int part_l=1, int part_r=-1)
Generates a random partition of a number.
Definition tgen.h:1854
std::vector< int > gen_partition_fixed_size(int n, int k, int part_l=0, int part_r=-1)
Generates a random partition with fixed size of a number.
Definition tgen.h:1917
uint64_t totient(uint64_t n)
Euler's totient function.
Definition tgen.h:1439
uint64_t prime_from(uint64_t l)
Computes smallest prime from given value.
Definition tgen.h:1578
std::vector< uint64_t > factor(uint64_t n)
Factors a number into primes.
Definition tgen.h:1375
int num_divisors(uint64_t n)
Computes the number of divisors of a given number.
Definition tgen.h:1650
bool is_prime(uint64_t n)
Checks if a number is prime.
Definition tgen.h:1314
uint64_t gen_prime(uint64_t l, uint64_t r)
Generates a random prime in given range.
Definition tgen.h:1554
constexpr int FFT_MOD
FFT/NTT mod.
Definition tgen.h:1802
uint64_t gen_congruent(uint64_t l, uint64_t r, uint64_t rem, uint64_t mod)
Generates random number in range given a modular congruence.
Definition tgen.h:1785
uint64_t gen_congruent(uint64_t l, uint64_t r, std::vector< uint64_t > rems, std::vector< uint64_t > mods)
Generates random number in range given modular congruences.
Definition tgen.h:1742
uint64_t gen_even(uint64_t l, uint64_t r)
Generates random even number in a given range.
Definition tgen.h:1792
uint64_t highly_composite_upto(uint64_t r)
Largest highly composite number up to given number.
Definition tgen.h:1544
std::vector< std::pair< uint64_t, int > > factor_by_prime(uint64_t n)
Factors a number into primes and its powers.
Definition tgen.h:1385
const std::vector< uint64_t > & fibonacci()
Fetches Fibonacci numbers.
Definition tgen.h:1805
uint64_t modular_inverse(uint64_t a, uint64_t mod)
Computes modular inverse.
Definition tgen.h:1433
uint64_t gen_divisor_count(uint64_t l, uint64_t r, int divisor_count)
Generates random number in range with a given prime number of divisors.
Definition tgen.h:1659
const std::vector< uint64_t > & highly_composites()
Fetches highly composite numbers.
Definition tgen.h:1504
T opt(const Key &key, std::optional< T > default_value=std::nullopt)
Gets opt by key.
Definition tgen.h:573
bool has_opt(std::size_t index)
Checks if opt at some index exists.
Definition tgen.h:559
bool has_opt(const std::string &key)
Checks if opt with with some key exists.
Definition tgen.h:565
void register_gen(int argc, char **argv)
Sets up the generator.
Definition tgen.h:595
instance gen() const
Generates a random instance from the set of valid permutations.
Definition tgen.h:1213
permutation & set(int idx, int value)
Restricts generator s.t. value at index is fixed.
Definition tgen.h:1112
permutation(int size)
Creates permutation generator defined by size.
Definition tgen.h:1107
instance gen(std::vector< int > cycle_sizes) const
Generates a random instance from the set of valid permutations, given a list of cycle sizes.
Definition tgen.h:1249
instance(const std::vector< int > &vec)
Creates a permutation instance from a std::vector.
Definition tgen.h:1126
int & operator[](int idx)
Returns the value at some position of the instance.
Definition tgen.h:1145
std::vector< int > to_std() const
Converts the instance to a std::vector.
Definition tgen.h:1208
int size() const
Returns the size of the permutation instance.
Definition tgen.h:1142
instance & reverse()
Reverses the instance.
Definition tgen.h:1174
instance & add_1()
Adds 1 for printing.
Definition tgen.h:1191
instance & sort()
Sorts the instance in non-decreasing order.
Definition tgen.h:1166
instance & inverse()
Inverse of the permutation.
Definition tgen.h:1181
int parity() const
Parity of the permutation.
Definition tgen.h:1150
sequence(int size, std::set< T > values)
Creates sequence generator define by value set.
Definition tgen.h:638
sequence & distinct(std::set< int > indices)
Restricts generator s.t. all values at index set are distinct.
Definition tgen.h:700
sequence & different(int idx_1, int idx_2)
Restricts generator s.t. values at two indices are different.
Definition tgen.h:707
sequence & distinct()
Restricts generator s.t. all values are distinct.
Definition tgen.h:713
instance gen() const
Generates a random instance from the set of valid sequences.
Definition tgen.h:828
sequence & equal_range(int left, int right)
Restricts generator s.t. all values at index range are the same.
Definition tgen.h:689
sequence & equal(int idx_1, int idx_2)
Restricts generator s.t. values at two indices are the same.
Definition tgen.h:676
sequence & set(int idx, T value)
Restricts generator s.t. value at index is fixed.
Definition tgen.h:651
sequence(int size, T value_l, T value_r)
Creates sequence generator define by size and range of values.
Definition tgen.h:629
instance & reverse()
Reverses the instance.
Definition tgen.h:747
instance operator+(const instance &rhs)
Concatenates two instances.
Definition tgen.h:754
instance(const std::vector< T > &vec)
Creates a sequence instance from a std::vector.
Definition tgen.h:727
const T & operator[](int idx) const
Returns the value at some position of the instance.
Definition tgen.h:736
int size() const
Returns the size of the sequence instance.
Definition tgen.h:732
instance & sort()
Sorts the instance in non-decreasing order.
Definition tgen.h:740
std::vector< T > to_std() const
Converts the instance to a std::vector.
Definition tgen.h:773
Permutation instance.
Definition tgen.h:1120
Permutation generator.
Definition tgen.h:1102
Printer helper for standard types.
Definition tgen.h:149
Sequence instance.
Definition tgen.h:721
Sequence generator.
Definition tgen.h:615