forked from the-hyp0cr1t3/CC
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRandom number generation.cpp
132 lines (112 loc) · 4.48 KB
/
Random number generation.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* Random namespace */
namespace Randnum {
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define EnableIntegral typename = enable_if_t<is_integral<T>::value>
template<typename T = int, EnableIntegral>
T randInt(int64_t L, int64_t R) { // [L, R] inclusive
uniform_int_distribution<T> d(L, R);
return d(rng);
}
template<typename T = int, EnableIntegral>
T randInt(int64_t n) { // [0, n)
return randInt<T>(0, n-1);
}
template<typename T = int, EnableIntegral>
vector<T> randArray(int n, int64_t L, int64_t R) {
vector<T> v(n);
for(auto& x: v)
x = randInt<T>(L, R);
return v;
}
template<typename T>
void shuffle(vector<T>& v) {
shuffle(v.begin(), v.end(), rng);
}
const string binary = "01";
const string digits = "0123456789";
const string alpha = "abcdefghijklmnopqrstuvwxyz";
const string alphanum = alpha + digits;
string randString(int n, const string& charset = alpha) {
string res; int len = charset.size();
for(int i = 0; i < n; i++)
res.push_back(charset[randInt(len)]);
return res;
}
/** Weighted random in range [0, n)
* w_randInt(n, t) = max(randInt(n), randInt(n),... randInt(n)) ~--- t times
* if t < 0, min is taken
* magnitude is number of iterations **/
template<typename T = int, EnableIntegral>
T w_randInt(int64_t n, int type) {
T result = randInt<T>(n);
for(int i = 0; i < type; i++) {
T nxt = randInt<T>(n);
result = result < nxt? nxt : result;
} for(int i = 0; i < -type; i++) {
T nxt = randInt<T>(n);
result = result > nxt? nxt : result;
} return result;
}
enum InputFormat { Edges, Parents };
/** Random tree generator (1-indexed) **/
template<InputFormat inp = Edges>
auto randTree(int n, int elongation = 2e9) {
if(elongation == 2e9) // radomized if not passed as an arg
elongation = randInt(1, n); // +ve elong => rope-y, -ve elong => star-y
vector<int> perm(n);
iota(perm.begin(), perm.end(), 0);
shuffle(perm); // shuffle(perm.begin()+1, perm.end(), rng) to root at 1
vector<int> p(n);
for(int i = 1; i < n; i++)
p[i] = w_randInt(i, elongation);
if constexpr(inp == Parents) { // ----- Parents ------
vector<int> par(n, -1);
for(int i = 1; i < n; i++)
par[perm[i]] = perm[p[i]] + 1;
return par;
} else { // ----- Edges -------
vector<pair<int, int>> edges; edges.reserve(n-1);
for(int i = 1; i < n; i++)
edges.push_back(randInt(2)?
pair{perm[i] + 1, perm[p[i]] + 1}
: pair{perm[p[i]] + 1, perm[i] + 1});
return shuffle(edges), edges;
}
}
/** Random k-ary tree generator (1-indexed) **/
// k = 1 for rope/chain, k = n-1 for star
template<InputFormat inp = Edges>
auto randTreeKary(int n, int k) {
vector<int> perm(n);
iota(perm.begin(), perm.end(), 0);
shuffle(perm);
if constexpr(inp == Parents) { // ----- Parents -----
vector<int> par(n, -1);
for(int i = 0, j = 1; j < n; i++, j+=k)
for(int id = j; id < min(n, j+k); id++)
par[perm[id]] = perm[i] + 1;
return par;
} else { // ----- Edges -------
vector<pair<int, int>> edges; edges.reserve(n-1);
for(int i = 0, j = 1; j < n; i++, j += k)
for(int id = j; id < min(n, j+k); id++)
edges.push_back(randInt(2)?
pair{perm[i] + 1, perm[id] + 1}
: pair{perm[id] + 1, perm[i] + 1});
return shuffle(edges), edges;
}
}
}
/*
int main() {
using namespace Randnum;
int n = randInt(2, 5);
int64_t m = randInt<int64_t>(12345678901234567LL);
string s = randString(n, alpha);
vector<int64_t> vec = randArray<int64_t>(n, 0, 1ll<<62);
shuffle(vec);
vector<pair<int, int>> edges = randTree<Edges>(n);
vector<int> parents = randTree<Parents>(n, -n/2);
vector<pair<int, int>> karyedges = randTreeKary(n, randInt(1, n-1));
} // ~W
*/