2222#include < string>
2323#include < cstdlib>
2424#include < vector>
25+ #include < cassert>
2526#define WANT_TEST_EXTRAS
2627#include < tap++/tap++.h>
2728
@@ -33,6 +34,8 @@ using namespace TAP;
3334
3435char short_sample[]=" 1234567" ;
3536char longer_sample[]=" z1234567*89abcde&fghijklmnopqrstuvwxyzAB%CDEFGHIJKLMNOPQRSTUVWXYZ!" ;
37+ unsigned char bin_sample[]= {49, 22, 152, 226, 89, 119, 247, 115, 43, 42, 243, 71, 234, 231, 91, 35, 78, 108, 115, 39, 181, 248, 211, 52, 47, 94, 60, 237, 18, 39, 148, 62, 205, 214, 156, 184, 18, 201, 84, 183, 74, 134, 94, 72, 14, 116, 145, 109, 1, 230, 17, 95, 154, 100, 60, 15, 12, 102, 20, 115, 35, 183, 47, 176, 78, 176, 189, 113, 131, 93, 206, 62, 158, 166, 131, 95, 232, 217, 32, 171, 87, 31, 172, 160, 66, 160, 222, 134, 253, 1, 7, 191, 91, 125, 81, 148, 41, 46, 38, 171, 83, 215, 79, 34, 23, 215, 183, 118, 236, 191, 59, 160, 135, 58, 32, 199, 170, 183, 213, 53, 162, 138, 178, 118, 23, 202, 133, 8, 192, 183, 195, 199, 250, 29, 230, 34, 159, 10, 145, 74, 121, 85, 168, 204, 192, 25, 232, 88, 85, 76, 61, 168, 247, 128, 141, 176, 112, 113, 100, 201, 82, 183, 219, 236, 226, 171, 85, 97, 160, 1, 50, 250, 161, 51, 61, 220, 167, 227, 195, 17, 164, 211, 189, 130, 52, 167, 169, 42, 17, 29, 95, 15, 178, 165, 110, 87, 149, 214, 55, 12, 236, 138, 2, 245, 158, 84, 140, 24, 225, 169, 115, 16, 130, 253, 237, 182, 95, 109, 4, 28, 249, 4, 254, 166, 62, 107, 228, 113, 130, 127, 70, 79, 140, 41, 84, 218, 134, 146, 88, 65, 24, 174, 252, 253, 226, 214, 22, 92, 248, 14, 29, 60, 180, 94, 30, 186, 0};
38+
3639
3740
3841// class SimpeRecursionNode;
@@ -41,6 +44,99 @@ char longer_sample[]="z1234567*89abcde&fghijklmnopqrstuvwxyzAB%CDEFGHIJKLMNOPQRS
4144// class TestRNode3;
4245
4346
47+ template <class T > using my_refvector = std::vector<std::reference_wrapper<T>>; /* This defines my_refvector type a shortcut to std::vector<std::reference_wrapper<T>> */
48+
49+ class Variants
50+ {
51+ protected:
52+ int variant_count = 1 ;
53+ int variant_selected = -1 ;
54+ bool enabled = true ;
55+
56+ public:
57+ void SetVariantCount (int i) {variant_count = i;};
58+ int GetVariantCount (){if (enabled) return variant_count; return 0 ;};
59+ void SetVariantSelected (int i) {variant_selected = i;};
60+ int GetVariantSelected (){return variant_selected;};
61+ void Enable (){enabled = true ;};
62+ void Disable (){enabled = false ;};
63+ };
64+
65+ Variants&
66+ VariantPicker (my_refvector<Variants> ref_vec, unsigned char seed)
67+ {
68+ unsigned char max = 255 ;
69+ int total = 0 ;
70+ for (Variants& v : ref_vec)
71+ {
72+ total += v.GetVariantCount ();
73+ }
74+ double step = (double )max / total;
75+ int i = 0 ;
76+ double sum = 0 ;
77+
78+
79+ Variants * last_variant;
80+
81+ for (Variants& v : ref_vec)
82+ {
83+ if (v.GetVariantCount () == 0 )
84+ continue ;
85+ last_variant = &v;
86+ for (i=0 ; i <v.GetVariantCount (); i++)
87+ {
88+ sum += step /* * v.GetVariantCount()*/ ;
89+ if (seed <= sum)
90+ {
91+ v.SetVariantSelected (i);
92+ return v;
93+ }
94+ }
95+ }
96+
97+ // there mught be problem with precision that will not allow us to catch last item
98+ // but delta should be small. In other cases terminating
99+ if (abs ( seed - sum) >0.1 )
100+ {
101+ fprintf (stderr," Something is really wrong\n " );
102+ exit (1 );
103+ }
104+ /* FIXME here we should solve case when there in no variants. Now it will segfault here */
105+ last_variant->SetVariantSelected (last_variant->GetVariantCount ()-1 );
106+
107+ return ref_vec.back (); /* FIXME here should set last variant!!!*/
108+ }
109+
110+ std::vector<unsigned int >
111+ fit_sizes (std::vector<unsigned int > seeds, unsigned int fit_in)
112+ {
113+ long seed_sum = 0 ;
114+ for (int seed : seeds)
115+ {
116+ seed_sum += seed;
117+ }
118+ double proportion = (double ) fit_in / (double ) seed_sum;
119+
120+ double remainder = 0 ;
121+
122+ std::vector<unsigned int > res;
123+
124+ int res_sum = 0 ;
125+ for (int seed : seeds)
126+ {
127+ double d_size = (double ) seed * proportion + remainder;
128+ unsigned int size = round (d_size);
129+ remainder = d_size - size;
130+ res.push_back (size);
131+ res_sum += size;
132+ }
133+ assert (res_sum == fit_in);
134+ return res;
135+ }
136+
137+
138+
139+
44140template <class T > class WeightedRef
45141{
46142 public:
@@ -97,34 +193,45 @@ WeightedRefPicker<T>::pick(unsigned char c)
97193class GalleySimpleRecusion ;
98194
99195
100- class SimpeRecursionNode : public StampBase
196+ class SimpeRecursionNode : public StampBase , public Variants
101197{
102198
103199 public:
104200 GalleySimpleRecusion * recursor;
105201 virtual std::string do_recursion (Blob &blob) = 0;
106202
203+ virtual std::string tmpID () = 0;
107204};
108205class TestRNode1 : public SimpeRecursionNode
109206{
207+ std::vector<std::string> operations = {" +" ," -" ," *" ," /" ," ^" } ;
110208 public:
111209 virtual std::string do_recursion (Blob &blob) override ;
112210 int minSize () override {return 1 ; }; // FIXME correct it
113211 int maxSize () override {return -1 ;}; /* Sereies always takes as much data as it can take */
212+
213+ TestRNode1 () {SetVariantCount (operations.size ());};
214+
215+ std::string tmpID () override {return " A" ;};
114216};
217+
115218class TestRNode2 : public SimpeRecursionNode
116219{
117220 public:
118221 virtual std::string do_recursion (Blob &blob) override ;
119222 int minSize () override {return 1 ; }; // FIXME correct it
120223 int maxSize () override {return -1 ;}; /* Sereies always takes as much data as it can take */
224+
225+ std::string tmpID () override {return " B" ;}
121226};
122227class TestRNode3 : public SimpeRecursionNode
123228{
124229 public:
125230 virtual std::string do_recursion (Blob &blob) override ;
126231 int minSize () override {return 1 ; }; // FIXME correct it
127232 int maxSize () override {return -1 ;}; /* Sereies always takes as much data as it can take */
233+
234+ std::string tmpID () override {return " C" ;}
128235};
129236
130237class GalleySimpleRecusion : public GalleyBase
@@ -133,7 +240,7 @@ class GalleySimpleRecusion : public GalleyBase
133240 TestRNode2 node2;
134241 TestRNode3 node3;
135242
136- std::vector<std::reference_wrapper<SimpeRecursionNode>> stamps = {node1, node2, node3};
243+ std::vector<std::reference_wrapper<SimpeRecursionNode>> stamps = {node1/* , node2, node3*/ };
137244
138245 public:
139246 int minSize () override {return 1 ; }; // FIXME correct it
@@ -150,15 +257,46 @@ class GalleySimpleRecusion : public GalleyBase
150257std::string
151258TestRNode1::do_recursion (Blob &blob)
152259{
260+ int variant_n = GetVariantSelected (); /* Copy it as early as possible as it can be overwritten while recursion */
261+
262+ StampArithm<unsigned char > stamp_char;
263+
264+ StampArithm<unsigned short int > stamp_sint;
265+
266+ unsigned short int spl_val;
267+
268+ if (blob.Size () < (stamp_sint.minSize () + 4 * stamp_char.minSize ()) )
269+ {
270+ try {
271+ std::string val = stamp_char.ExtractStr (blob);
272+ return val;
273+ }
274+ catch (OutOfData)
275+ {
276+ printf (" ___________________________ %i\n " , blob.Size ());
277+ return " Q" ;
278+ }
279+
280+ }
281+
153282 try {
154- Blob tmp = blob. ShiftBytes ( 1 );
283+ spl_val = stamp_sint. ExtractValue (blob );
155284 }
156285 catch (OutOfData)
157286 {
158- return " 0 " ;
287+ return " Z " ;
159288 }
160289
161- return " 1 + " + recursor->do_recursion (blob);
290+ std::vector<unsigned int > split_data_in = {spl_val, (unsigned short int ) std::numeric_limits<unsigned short int >::max () - spl_val };
291+ std::vector<unsigned int > split_data = fit_sizes (split_data_in, blob.Size () - 4 * stamp_char.minSize ());
292+
293+ printf (" llll - %i %i \n " , split_data[0 ], split_data[1 ]);
294+
295+ Blob blob_left = blob.ShiftBytes (split_data[0 ]+ 2 *stamp_char.minSize () );
296+
297+ printf (" ~~~ %i\n " ,variant_n);
298+
299+ return " (" + recursor->do_recursion (blob_left) + " " + operations[variant_n] +" " + recursor->do_recursion (blob)+" )" ;
162300}
163301
164302std::string
@@ -193,8 +331,10 @@ TestRNode3::do_recursion(Blob &blob)
193331std::string
194332GalleySimpleRecusion::do_recursion (Blob& blob)
195333{
196- StampArithm<char > stamp_char;
197- char c;
334+
335+
336+ StampArithm<unsigned char > stamp_char;
337+ unsigned char c;
198338 try {
199339 c = stamp_char.ExtractValue (blob);
200340 }
@@ -203,10 +343,35 @@ GalleySimpleRecusion::do_recursion(Blob& blob)
203343 return " 0" ;
204344 }
205345
206- c = c % 3 ;
207346
208- SimpeRecursionNode &node = stamps[c];
347+ std::vector<std::reference_wrapper<Variants>> stamps_v = {node1/* , node2, node3*/ };
348+
349+
350+ /* printf("=================================\n");
351+
352+
353+ for(int i = 0; i<256;i+=1)
354+ {
355+
356+ SimpeRecursionNode& res_node = (SimpeRecursionNode&) VariantPicker(stamps_v, i);
357+ printf("--- %s - %i \n",res_node.tmpID().c_str(), res_node.GetVariantSelected());
358+ }
359+
360+ */
361+
362+
363+ // c = c % 3;
364+
365+ // SimpeRecursionNode &node = stamps[c];
209366// TestRNode3 node;
367+
368+
369+
370+ SimpeRecursionNode& node = (SimpeRecursionNode&) VariantPicker (stamps_v, c);
371+
372+ printf (" --- %s - %i - %i \n " ,node.tmpID ().c_str (), c, node.GetVariantSelected ());
373+
374+
210375 node.recursor = this ;
211376 return node.do_recursion (blob);
212377}
@@ -215,11 +380,20 @@ GalleySimpleRecusion::do_recursion(Blob& blob)
215380
216381
217382
218-
219383int
220384main ()
221385 {
222386
387+ std::vector<unsigned int > v = {1 ,20 ,30 ,10 ,1 };
388+
389+ std::vector<unsigned int > res = fit_sizes (v, 6 );
390+ for ( unsigned int i : res)
391+ {
392+ printf (" *** %i\n " ,i);
393+ }
394+
395+
396+ /*
223397 char c1='a';
224398 char c2='b';
225399 char c3='c';
@@ -232,11 +406,12 @@ main()
232406 char &rc = wrp.pick(i);
233407 fprintf(stderr,"^^ %i %c\n",i,rc);
234408
235- }
409+ } */
236410
237411 TEST_START (1 );
238412 {
239- Blob blob (short_sample, strlen (short_sample));
413+ // Blob blob(short_sample, strlen(short_sample));
414+ Blob blob ((char *)bin_sample, strlen ((char *)bin_sample));
240415 GalleySimpleRecusion galley;
241416
242417fprintf (stderr," --1\n " );
0 commit comments