1 | // https://www.mikrocontroller.net/topic/499612
|
2 |
|
3 | #include <iostream>
|
4 | #include <random>
|
5 | #include <functional>
|
6 | #include <vector>
|
7 | #include <algorithm>
|
8 | #include <chrono>
|
9 | #include "random_selector.h"
|
10 |
|
11 |
|
12 | constexpr unsigned max_tree_depth = 3;
|
13 |
|
14 | // evil globals
|
15 | std::vector< std::function<int(void)> > the_frs;
|
16 | std::vector< std::function<void(void)> > the_fas;
|
17 | std::vector< std::function<bool(int, int)> > the_int_ops;
|
18 | std::vector< std::function<bool(bool, bool)> > the_bool_ops;
|
19 |
|
20 | std::mt19937 gen; //Standard mersenne_twister_engine seeded with rd()
|
21 | std::uniform_int_distribution<> distrib(0, 5);
|
22 |
|
23 |
|
24 | std::function<bool()> create_condition_tree(unsigned depth=0)
|
25 | {
|
26 | unsigned d = distrib(gen);
|
27 | if (depth > max_tree_depth || d <= 2)
|
28 | {
|
29 | auto fa = *select_randomly(the_frs.begin(), the_frs.end());
|
30 | auto fb = *select_randomly(the_frs.begin(), the_frs.end());
|
31 | auto op = *select_randomly(the_int_ops.begin(), the_int_ops.end());
|
32 | return [fa, fb, op](){return op(fa(), fb());};
|
33 | }
|
34 | else
|
35 | {
|
36 | auto lht = create_condition_tree(depth+1);
|
37 | auto rht = create_condition_tree(depth+1);
|
38 | auto bop = *select_randomly(the_bool_ops.begin(), the_bool_ops.end());
|
39 | return [lht, rht, bop](){std::cout << " ["; auto l = lht(); auto r = rht(); std::cout << "]"; return bop(l, r);};
|
40 | }
|
41 | }
|
42 |
|
43 |
|
44 | int main(void)
|
45 | {
|
46 | auto t0 = std::chrono::high_resolution_clock::now();
|
47 |
|
48 | for (int i = 0; i < 100; ++i)
|
49 | the_frs.push_back( [i](){return i;});
|
50 |
|
51 | for (int i = 0; i < 100; ++i)
|
52 | the_fas.push_back( [i](){std::cout << "(FA" << i << ")\n";});
|
53 |
|
54 | the_int_ops.push_back( [](int a, int b){std::cout << "(" << a << "<" << b << ")"; return a < b;});
|
55 | the_int_ops.push_back( [](int a, int b){std::cout << "(" << a << ">" << b << ")"; return a > b;});
|
56 | the_int_ops.push_back( [](int a, int b){std::cout << "(" << a << "=" << b << ")"; return a == b;});
|
57 |
|
58 | the_bool_ops.push_back([](bool a, bool b){bool r =a&&b; std::cout << "&&" << (r ? "yes ":"no "); return r;});
|
59 | the_bool_ops.push_back([](bool a, bool b){bool r =a||b; std::cout << "||" << (r ? "yes ":"no "); return r;});
|
60 | the_bool_ops.push_back([](bool a, bool b){bool r =a!=b; std::cout << "!=" << (r ? "yes ":"no "); return r;});
|
61 |
|
62 | std::vector< std::function<void(void)> > the_combinations;
|
63 |
|
64 | for(int i = 0; i < 100; ++i)
|
65 | {
|
66 | auto condition = create_condition_tree();
|
67 | auto action = *select_randomly(the_fas.begin(), the_fas.end());
|
68 | the_combinations.push_back([condition, action](){std::cout << "\n"; if (condition()){std::cout << " OK ==> "; action();} else std::cout << " FAIL\n"; } );
|
69 | }
|
70 | auto t1 = std::chrono::high_resolution_clock::now();
|
71 | for(auto c: the_combinations)
|
72 | c();
|
73 | auto t2 = std::chrono::high_resolution_clock::now();
|
74 | auto t_fill_us = std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count();
|
75 | auto t_run_us = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();
|
76 | std::cout << "FINISHED, filling took " << t_fill_us << "us, running " << t_run_us << "us\n";
|
77 | }
|