Skip to content

Commit f8170c1

Browse files
committed
Random with custom functions
1 parent c69916f commit f8170c1

File tree

4 files changed

+149
-128
lines changed

4 files changed

+149
-128
lines changed

array.h

+36-4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ class GenericArray : public ReprProxy<GenericArray<T>>, public std::vector<T> {
3636
using Base::insert;
3737
using Base::clear;
3838

39+
template<typename F, typename ...Args>
40+
static GenericArray<T> randomf(size_t size, F func, const Args& ... args);
41+
template<typename F, typename ...Args>
42+
static GenericArray<T> randomfUnique(size_t size, F func, const Args& ... args);
43+
3944
template<typename ...Args>
4045
static GenericArray<T> random(size_t size, const Args& ... args);
4146
template<typename ...Args>
@@ -82,6 +87,20 @@ GenericArray<T> GenericArray<T>::random(size_t size, const Args& ... args) {
8287
return result;
8388
}
8489

90+
template<typename T>
91+
template<typename F, typename ...Args>
92+
GenericArray<T> GenericArray<T>::randomf(
93+
size_t size,
94+
F func,
95+
const Args& ... args)
96+
{
97+
GenericArray<T> result(size);
98+
for (T& x: result) {
99+
x = func(args...);
100+
}
101+
return result;
102+
}
103+
85104
namespace detail {
86105

87106
template<typename T, typename Enable = std::size_t>
@@ -98,9 +117,11 @@ struct DictContainer<T, typename std::hash<T>::result_type>
98117
} // namespace detail
99118

100119
template<typename T>
101-
template<typename ...Args>
102-
GenericArray<T> GenericArray<T>::randomUnique(
103-
size_t size, const Args& ... args)
120+
template<typename F, typename ...Args>
121+
GenericArray<T> GenericArray<T>::randomfUnique(
122+
size_t size,
123+
F func,
124+
const Args& ... args)
104125
{
105126
typename detail::DictContainer<T>::type set;
106127
GenericArray<T> result;
@@ -113,7 +134,7 @@ GenericArray<T> GenericArray<T>::randomUnique(
113134
ensure(false, "There are not enough unique elements");
114135
}
115136

116-
T t = rnd.tnext<T>(args...);
137+
T t = func(args...);
117138
if (!set.count(t)) {
118139
set.insert(t);
119140
result.push_back(t);
@@ -123,6 +144,17 @@ GenericArray<T> GenericArray<T>::randomUnique(
123144
return result;
124145
}
125146

147+
template<typename T>
148+
template<typename ...Args>
149+
GenericArray<T> GenericArray<T>::randomUnique(
150+
size_t size, const Args& ... args)
151+
{
152+
return GenericArray<T>::randomfUnique(
153+
size,
154+
rnd.tnext<T, Args...>,
155+
args...);
156+
}
157+
126158
template<typename T>
127159
GenericArray<T> GenericArray<T>::id(size_t size, T start) {
128160
constexpr bool enable = std::is_integral<T>::value;

jngen.h

+73-123
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class Random {
132132
}
133133

134134
template<typename T, typename ... Args>
135-
T tnext(Args... args) {
135+
static T tnext(Args... args) {
136136
return TypedRandom<T>::next(args...);
137137
}
138138
};
@@ -215,124 +215,6 @@ void registerGen(int argc, char *argv[]) {
215215

216216
namespace impl {
217217

218-
namespace pattern {
219-
220-
/*
221-
Here we go with patterns of kind 'ab{2-10}[c-f][^1-9]{16}'. The grammar is
222-
described further.
223-
224-
Pattern ::= Block | Block Pattern
225-
Block ::= Set | Set Count
226-
Count ::= {int} | {int-int} // int - regular integer
227-
Set ::= [PosSet] | [NegSet] | Char
228-
NegSet ::= ^ Subset
229-
PosSet ::= x Subset // x -- any char except ^
230-
Subset ::= Range | Range Set
231-
Range ::= Char | Char-Char
232-
Char ::= c | \ Special // c -- any non-special
233-
Special ::= [ ] \ - { }
234-
*/
235-
236-
struct Set {
237-
static const char MIN = 32;
238-
static const char MAX = 127;
239-
240-
std::vector<char> allowed; // should be bool but <s>int is faster</s> who cares
241-
242-
void negate() {
243-
std::vector<char> all(MAX - MIN + 1);
244-
std::iota(all.begin(), all.end(), MIN);
245-
std::vector<char> result;
246-
set_symmetric_difference(
247-
allowed.begin(), allowed.end(),
248-
all.begin(), all.end(),
249-
std::back_inserter(result));
250-
allowed = result;
251-
}
252-
253-
Set() {}
254-
255-
Set(const std::bitset<256>& bitset) {
256-
for (int i = MIN; i <= MAX; ++i) {
257-
if (bitset[i]) {
258-
allowed.push_back(i);
259-
}
260-
}
261-
}
262-
};
263-
264-
typedef std:pair<int, int> Range;
265-
266-
struct Block {
267-
Set set;
268-
Range range;
269-
};
270-
271-
struct Pattern {
272-
std::vector<Block> blocks;
273-
274-
std::string generate(std::function<size_t>(size_t)&& randomEngine);
275-
};
276-
277-
class Parser {
278-
public:
279-
Parser(const std::string& pattern) : pattern_(pattern) {}
280-
281-
Pattern parse();
282-
283-
private:
284-
Block parseBlock();
285-
286-
int next() const {
287-
return position_ < pattern_.size() ? pattern_[position_] : -1;
288-
}
289-
290-
std::string pattern_;
291-
size_t position_;
292-
};
293-
294-
struct ParsingException : public std::logic_error {};
295-
296-
Pattern Parser::parse() {
297-
ensure(position_ == 0, "Cannot parse the same pattern more than once");
298-
299-
Pattern result;
300-
301-
try {
302-
while (position_ != pattern_.size()) {
303-
result.blocks.push_back(parseBlock());
304-
}
305-
return resut;
306-
} catch (ParsingException& e) {
307-
std::string msg = "Failed to parse the pattern: '" + pattern_ + "'";
308-
ensure(false, msg);
309-
}
310-
311-
return resut;
312-
}
313-
314-
Block Parser::parseBlock() {
315-
// 1) parse set
316-
317-
int first = next();
318-
if (first == -1) {
319-
throw ParsingException();
320-
}
321-
322-
std::bitset<256> allowed;
323-
bool negate = first == '^';
324-
if (!negate) {
325-
allowed[first] = true;
326-
}
327-
328-
} // namespace detail
329-
330-
} // namespace impl
331-
332-
#include <bits/stdc++.h>
333-
334-
namespace impl {
335-
336218
class Dsu {
337219
public:
338220
int getParent(int x) {
@@ -888,6 +770,11 @@ class GenericArray : public ReprProxy<GenericArray<T>>, public std::vector<T> {
888770
using Base::insert;
889771
using Base::clear;
890772

773+
template<typename F, typename ...Args>
774+
static GenericArray<T> randomf(size_t size, F func, const Args& ... args);
775+
template<typename F, typename ...Args>
776+
static GenericArray<T> randomfUnique(size_t size, F func, const Args& ... args);
777+
891778
template<typename ...Args>
892779
static GenericArray<T> random(size_t size, const Args& ... args);
893780
template<typename ...Args>
@@ -934,6 +821,20 @@ GenericArray<T> GenericArray<T>::random(size_t size, const Args& ... args) {
934821
return result;
935822
}
936823

824+
template<typename T>
825+
template<typename F, typename ...Args>
826+
GenericArray<T> GenericArray<T>::randomf(
827+
size_t size,
828+
F func,
829+
const Args& ... args)
830+
{
831+
GenericArray<T> result(size);
832+
for (T& x: result) {
833+
x = func(args...);
834+
}
835+
return result;
836+
}
837+
937838
namespace detail {
938839

939840
template<typename T, typename Enable = std::size_t>
@@ -950,9 +851,11 @@ struct DictContainer<T, typename std::hash<T>::result_type>
950851
} // namespace detail
951852

952853
template<typename T>
953-
template<typename ...Args>
954-
GenericArray<T> GenericArray<T>::randomUnique(
955-
size_t size, const Args& ... args)
854+
template<typename F, typename ...Args>
855+
GenericArray<T> GenericArray<T>::randomfUnique(
856+
size_t size,
857+
F func,
858+
const Args& ... args)
956859
{
957860
typename detail::DictContainer<T>::type set;
958861
GenericArray<T> result;
@@ -965,7 +868,7 @@ GenericArray<T> GenericArray<T>::randomUnique(
965868
ensure(false, "There are not enough unique elements");
966869
}
967870

968-
T t = rnd.tnext<T>(args...);
871+
T t = func(args...);
969872
if (!set.count(t)) {
970873
set.insert(t);
971874
result.push_back(t);
@@ -975,6 +878,17 @@ GenericArray<T> GenericArray<T>::randomUnique(
975878
return result;
976879
}
977880

881+
template<typename T>
882+
template<typename ...Args>
883+
GenericArray<T> GenericArray<T>::randomUnique(
884+
size_t size, const Args& ... args)
885+
{
886+
return GenericArray<T>::randomfUnique(
887+
size,
888+
rnd.tnext<T, Args...>,
889+
args...);
890+
}
891+
978892
template<typename T>
979893
GenericArray<T> GenericArray<T>::id(size_t size, T start) {
980894
constexpr bool enable = std::is_integral<T>::value;
@@ -1159,6 +1073,42 @@ impl::GenericArray<T> makeArray(const std::initializer_list<T>& values) {
11591073
return impl::GenericArray<T>(values);
11601074
}
11611075

1076+
1077+
namespace impl {
1078+
1079+
class ArrayRandom {
1080+
public:
1081+
ArrayRandom() {
1082+
static bool created = false;
1083+
ensure(!created, "impl::ArrayRandom should be created only once");
1084+
created = true;
1085+
}
1086+
1087+
template<typename F, typename ...Args>
1088+
static auto randomf(
1089+
size_t size,
1090+
F func,
1091+
Args... args) -> GenericArray<decltype(func(args...))>
1092+
{
1093+
typedef decltype(func(args...)) T;
1094+
return GenericArray<T>::randomf(size, func, args...);
1095+
}
1096+
1097+
template<typename F, typename ...Args>
1098+
static auto randomfUnique(
1099+
size_t size,
1100+
F func,
1101+
Args... args) -> GenericArray<decltype(func(args...))>
1102+
{
1103+
typedef decltype(func(args...)) T;
1104+
return GenericArray<T>::randomfUnique(size, func, args...);
1105+
}
1106+
} rnda;
1107+
1108+
} // namespace impl
1109+
1110+
using impl::rnda;
1111+
11621112
#include <bits/stdc++.h>
11631113

11641114

random.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class Random {
7373
}
7474

7575
template<typename T, typename ... Args>
76-
T tnext(Args... args) {
76+
static T tnext(Args... args) {
7777
return TypedRandom<T>::next(args...);
7878
}
7979
};

rnda.h

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#pragma once
2+
3+
#include "common.h"
4+
#include "array.h"
5+
6+
namespace impl {
7+
8+
class ArrayRandom {
9+
public:
10+
ArrayRandom() {
11+
static bool created = false;
12+
ensure(!created, "impl::ArrayRandom should be created only once");
13+
created = true;
14+
}
15+
16+
template<typename F, typename ...Args>
17+
static auto randomf(
18+
size_t size,
19+
F func,
20+
Args... args) -> GenericArray<decltype(func(args...))>
21+
{
22+
typedef decltype(func(args...)) T;
23+
return GenericArray<T>::randomf(size, func, args...);
24+
}
25+
26+
template<typename F, typename ...Args>
27+
static auto randomfUnique(
28+
size_t size,
29+
F func,
30+
Args... args) -> GenericArray<decltype(func(args...))>
31+
{
32+
typedef decltype(func(args...)) T;
33+
return GenericArray<T>::randomfUnique(size, func, args...);
34+
}
35+
} rnda;
36+
37+
} // namespace impl
38+
39+
using impl::rnda;

0 commit comments

Comments
 (0)