PageRenderTime 26ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/c-language/file:.fxtdir/demo/comb/descent-rgs-stats-demo.cc

https://gitlab.com/Gentio/my-pdf
C++ | 403 lines | 112 code | 60 blank | 231 comment | 5 complexity | ee492b55aefc4a2c5ee1543d96b5cd73 MD5 | raw file
  1. #include "comb/descent-rgs.h"
  2. #include "comb/word-stats.h"
  3. #include "comb/comb-print.h"
  4. #include "fxtio.h"
  5. #include "fxttypes.h"
  6. #include "jjassert.h"
  7. #include "nextarg.h"
  8. //% Statistics for descent sequences.
  9. //% A descent sequence is a sequence [d(1), d(2), ..., d(n)] where d(1)=0,
  10. //% d(k)>=0, and d(k) <= 1 + desc([d(1), d(2), ..., d(k-1)]) and desc(.)
  11. //% counts the number of descents of its argument.
  12. //% Cf. the following OEIS sequences:
  13. //% A225624: triangle, length-n descent sequences with k-1 descents.
  14. // Cf. comb/ascent-rgs-stats-demo.cc for stats for ascent sequences
  15. // Cf. comb/descent-rgs-demo.cc
  16. //#define TIMING // uncomment to disable printing
  17. int
  18. main(int argc, char **argv)
  19. {
  20. ulong n = 5;
  21. NXARG(n, "Length of strings, n>=1");
  22. ulong sq = 1;
  23. NXARG(sq, "Select stats:\n"
  24. " 0 ==> max element\n"
  25. " 1 ==> number of descents\n"
  26. " 2 ==> number of ascents\n"
  27. " 3 ==> number of zeros - 1\n"
  28. " 4 ==> number of maximal digits - 1\n"
  29. " 6 ==> position of last occurrence of zero\n"
  30. " 7 ==> position of first occurrence of the maximal value\n"
  31. " 8 ==> position of last occurrence of the maximal value\n"
  32. " 10 ==> number of odd values\n"
  33. " 40 ==> number of flat steps\n"
  34. // " 80 ==> number of fixed points - 1\n"
  35. );
  36. descent_rgs A(n);
  37. word_stats W(A.data(), n);
  38. ulong ct = 0;
  39. ulong * st = new ulong[n+1]; // stats
  40. for (ulong k=0; k<=n; ++k) st[k] = 0;
  41. #ifndef TIMING
  42. const ulong *x = A.data();
  43. #endif
  44. ulong j = 0;
  45. do
  46. {
  47. ++ct;
  48. ulong s = 0;
  49. switch ( sq )
  50. {
  51. case 0: // by max element: A000000
  52. s = W.max_val();
  53. break;
  54. // 1,
  55. // 1, 1,
  56. // 1, 3, 0,
  57. // 1, 7, 1, 0,
  58. // 1, 15, 7, 0, 0,
  59. // 1, 31, 32, 3, 0, 0,
  60. // 1, 63, 122, 35, 1, 0, 0,
  61. // 1, 127, 423, 249, 32, 0, 0, 0,
  62. // 1, 255, 1389, 1413, 421, 22, 0, 0, 0,
  63. // 1, 511, 4414, 7078, 3789, 606, 13, 0, 0, 0,
  64. // 1, 1023, 13744, 32898, 27738, 8859, 794, 5, 0, 0, 0,
  65. // 1, 2047, 42245, 145854, 179415, 94394, 19131, 925, 1, 0, 0, 0,
  66. case 1: // by number of descents: A225624
  67. s = A.num_descents(); // simplified: s==A.m[n-1]
  68. // jjassert( s == W.num_ascents() );
  69. break;
  70. // 1,
  71. // 2, 0,
  72. // 3, 1, 0,
  73. // 4, 5, 0, 0,
  74. // 5, 15, 3, 0, 0,
  75. // 6, 35, 25, 1, 0, 0,
  76. // 7, 70, 117, 28, 0, 0, 0,
  77. // 8, 126, 405, 271, 22, 0, 0, 0,
  78. // 9, 210, 1155, 1631, 483, 13, 0, 0, 0,
  79. // 10, 330, 2871, 7359, 5126, 711, 5, 0, 0, 0,
  80. // 11, 495, 6435, 27223, 36526, 13482, 889, 1, 0, 0, 0,
  81. // 12, 715, 13299, 86919, 199924, 151276, 30906, 962, 0, 0, 0, 0,
  82. case 2: // by number of ascents: A000000
  83. s = W.num_ascents();
  84. break;
  85. // 1,
  86. // 1, 1,
  87. // 1, 3, 0,
  88. // 1, 6, 2, 0,
  89. // 1, 10, 11, 1, 0,
  90. // 1, 15, 36, 15, 0, 0,
  91. // 1, 21, 91, 97, 12, 0, 0,
  92. // 1, 28, 196, 421, 180, 6, 0, 0,
  93. // 1, 36, 378, 1435, 1411, 239, 1, 0, 0,
  94. // 1, 45, 672, 4148, 7821, 3506, 219, 0, 0, 0,
  95. // 1, 55, 1122, 10626, 34634, 31982, 6506, 136, 0, 0, 0,
  96. // 1, 66, 1782, 24805, 130729, 217829, 99620, 9129, 52, 0, 0, 0,
  97. // second col: A000217, g.f. x/(1-x)^3
  98. // third col: A005583, g.f.: x*(2-x)/(1-x)^6
  99. case 3: // by number of zeros (=min values): A000000
  100. s = W.num_zeros();
  101. // jjassert( s == W.num_min_val() );
  102. break;
  103. // 1,
  104. // 1, 1,
  105. // 1, 2, 1,
  106. // 1, 4, 3, 1,
  107. // 1, 8, 9, 4, 1,
  108. // 1, 17, 27, 16, 5, 1,
  109. // 1, 40, 85, 64, 25, 6, 1,
  110. // 1, 107, 289, 266, 125, 36, 7, 1,
  111. // 1, 329, 1078, 1174, 645, 216, 49, 8, 1,
  112. // 1, 1161, 4440, 5567, 3495, 1331, 343, 64, 9, 1,
  113. // 1, 4662, 20201, 28515, 20076, 8546, 2457, 512, 81, 10, 1,
  114. // 1, 21074, 101226, 157996, 122828, 57632, 18235, 4180, 729, 100, 11, 1,
  115. case 4: // by number of max digits: A000000
  116. s = W.num_max_val();
  117. break;
  118. // 1,
  119. // 1, 1,
  120. // 2, 1, 1,
  121. // 4, 3, 1, 1,
  122. // 10, 7, 4, 1, 1,
  123. // 31, 18, 11, 5, 1, 1,
  124. // 111, 57, 30, 16, 6, 1, 1,
  125. // 444, 213, 97, 47, 22, 7, 1, 1,
  126. // 1969, 892, 375, 156, 70, 29, 8, 1, 1,
  127. // 9643, 4123, 1638, 620, 240, 100, 37, 9, 1, 1,
  128. // 51864, 20985, 7871, 2813, 977, 356, 138, 46, 10, 1, 1,
  129. // 304526, 117141, 41485, 14028, 4585, 1482, 512, 185, 56, 11, 1, 1,
  130. case 6: // position of last zero (last occurrence of min): A000000
  131. s = W.last_zero_idx();
  132. // jjassert( s == W.last_min_idx() );
  133. break;
  134. // 1,
  135. // 1, 1,
  136. // 1, 1, 2,
  137. // 1, 1, 3, 4,
  138. // 1, 1, 5, 7, 9,
  139. // 1, 1, 10, 13, 19, 23,
  140. // 1, 1, 24, 28, 43, 58, 67,
  141. // 1, 1, 68, 70, 115, 156, 199, 222,
  142. // 1, 1, 223, 202, 361, 491, 625, 765, 832,
  143. // 1, 1, 833, 667, 1313, 1786, 2266, 2765, 3279, 3501,
  144. // 1, 1, 3502, 2497, 5451, 7410, 9352, 11395, 13461, 15580, 16412,
  145. // 1, 1, 16413, 10504, 25477, 34636, 43396, 52854, 62292, 71816, 81561, 85062,
  146. case 7: // position of first occurrence of max: A000000
  147. s = W.first_max_idx();
  148. break;
  149. // 1,
  150. // 1, 1,
  151. // 1, 2, 1,
  152. // 1, 4, 2, 2,
  153. // 1, 8, 4, 5, 5,
  154. // 1, 16, 8, 13, 14, 15,
  155. // 1, 32, 16, 35, 40, 47, 51,
  156. // 1, 64, 32, 97, 116, 151, 177, 194,
  157. // 1, 128, 64, 275, 340, 497, 631, 744, 821,
  158. // 1, 256, 128, 793, 1004, 1675, 2307, 2936, 3467, 3845,
  159. // 1, 512, 256, 2315, 2980, 5777, 8635, 11898, 15073, 17802, 19813,
  160. // 1, 1024, 512, 6817, 8876, 20371, 33027, 49412, 67313, 84844, 100116, 111700,
  161. case 8: // position of last occurrence of max: A000000
  162. s = W.last_max_idx();
  163. break;
  164. // 1,
  165. // 0, 2,
  166. // 0, 1, 3,
  167. // 0, 1, 2, 6,
  168. // 0, 1, 2, 6, 14,
  169. // 0, 1, 2, 8, 18, 38,
  170. // 0, 1, 2, 12, 28, 61, 118,
  171. // 0, 1, 2, 20, 48, 115, 230, 416,
  172. // 0, 1, 2, 36, 88, 241, 514, 966, 1653,
  173. // 0, 1, 2, 68, 168, 547, 1262, 2524, 4494, 7346,
  174. // 0, 1, 2, 132, 328, 1321, 3322, 7176, 13532, 23023, 36225,
  175. // 0, 1, 2, 260, 648, 3355, 9230, 21760, 43956, 78899, 129140, 196762,
  176. case 10: // number of odd values: (reversal of "even values")
  177. s = W.num_odd_val();
  178. break;
  179. // 1,
  180. // 1, 1,
  181. // 1, 2, 1,
  182. // 1, 4, 3, 1,
  183. // 1, 8, 9, 4, 1,
  184. // 1, 16, 26, 18, 5, 1,
  185. // 1, 32, 73, 74, 35, 6, 1,
  186. // 1, 65, 205, 285, 200, 68, 7, 1,
  187. // 1, 138, 591, 1077, 1025, 527, 133, 8, 1,
  188. // 1, 315, 1770, 4086, 5035, 3543, 1388, 264, 9, 1,
  189. // 1, 783, 5522, 15722, 24298, 22259, 12179, 3746, 541, 10, 1,
  190. // 1, 2114, 18018, 61970, 117030, 134294, 96417, 42451, 10534, 1172, 11, 1,
  191. case 11: // number of even values: A000000
  192. s = W.num_even_val();
  193. break;
  194. // 1,
  195. // 1, 1,
  196. // 1, 2, 1,
  197. // 1, 3, 4, 1,
  198. // 1, 4, 9, 8, 1,
  199. // 1, 5, 18, 26, 16, 1,
  200. // 1, 6, 35, 74, 73, 32, 1,
  201. // 1, 7, 68, 200, 285, 205, 65, 1,
  202. // 1, 8, 133, 527, 1025, 1077, 591, 138, 1,
  203. // 1, 9, 264, 1388, 3543, 5035, 4086, 1770, 315, 1,
  204. // 1, 10, 541, 3746, 12179, 22259, 24298, 15722, 5522, 783, 1,
  205. // 1, 11, 1172, 10534, 42451, 96417, 134294, 117030, 61970, 18018, 2114, 1,
  206. case 40: // number of flat steps: A000000
  207. s = W.num_flat_steps();
  208. break;
  209. // 1,
  210. // 1, 1,
  211. // 1, 2, 1,
  212. // 2, 3, 3, 1,
  213. // 4, 8, 6, 4, 1,
  214. // 11, 20, 20, 10, 5, 1,
  215. // 34, 66, 60, 40, 15, 6, 1,
  216. // 124, 238, 231, 140, 70, 21, 7, 1,
  217. // 512, 992, 952, 616, 280, 112, 28, 8, 1,
  218. // 2380, 4608, 4464, 2856, 1386, 504, 168, 36, 9, 1,
  219. // 12294, 23800, 23040, 14880, 7140, 2772, 840, 240, 45, 10, 1,
  220. // 69972, 135234, 130900, 84480, 40920, 15708, 5082, 1320, 330, 55, 11, 1,
  221. // 435399, 839664, 811404, 523600, 253440, 98208, 31416, 8712, 1980, 440, 66, 12, 1,
  222. case 41: // number of non-flat steps: A000000
  223. s = W.num_nonflat_steps();
  224. break;
  225. // 1,
  226. // 1, 1,
  227. // 1, 2, 1,
  228. // 1, 3, 3, 2,
  229. // 1, 4, 6, 8, 4,
  230. // 1, 5, 10, 20, 20, 11,
  231. // 1, 6, 15, 40, 60, 66, 34,
  232. // 1, 7, 21, 70, 140, 231, 238, 124,
  233. // 1, 8, 28, 112, 280, 616, 952, 992, 512,
  234. // 1, 9, 36, 168, 504, 1386, 2856, 4464, 4608, 2380,
  235. // 1, 10, 45, 240, 840, 2772, 7140, 14880, 23040, 23800, 12294,
  236. // 1, 11, 55, 330, 1320, 5082, 15708, 40920, 84480, 130900, 135234, 69972,
  237. // 1, 12, 66, 440, 1980, 8712, 31416, 98208, 253440, 523600, 811404, 839664, 435399,
  238. // case 60: // maxval - minval == maxval
  239. // s = W.min_max_diff();
  240. // break;
  241. case 61: // abs(#minval - #maxval): A000000
  242. s = W.min_max_num_diff();
  243. break;
  244. // 1,
  245. // 2, 0,
  246. // 1, 3, 0,
  247. // 4, 1, 4, 0,
  248. // 2, 13, 3, 5, 0,
  249. // 15, 12, 28, 6, 6, 0,
  250. // 17, 78, 55, 55, 10, 7, 0,
  251. // 96, 163, 280, 172, 98, 15, 8, 0,
  252. // 235, 769, 957, 928, 421, 161, 21, 9, 0,
  253. // 1087, 2717, 4561, 4303, 2581, 877, 248, 28, 10, 0,
  254. // 4232, 12861, 21356, 23570, 14850, 6151, 1632, 363, 36, 11, 0,
  255. // 20664, 61532, 114442, 134350, 94699, 41973, 12991, 2795, 510, 45, 12, 0,
  256. case 80: // by number of fixed points:
  257. s = W.num_fixed_points();
  258. break;
  259. // 1,
  260. // 1, 1,
  261. // 2, 2, 0,
  262. // 4, 5, 0, 0,
  263. // 9, 14, 0, 0, 0,
  264. // 23, 44, 0, 0, 0, 0,
  265. // 67, 155, 0, 0, 0, 0, 0,
  266. // 222, 610, 0, 0, 0, 0, 0, 0,
  267. // 832, 2669, 0, 0, 0, 0, 0, 0, 0,
  268. // 3501, 12911, 0, 0, 0, 0, 0, 0, 0, 0,
  269. // 16412, 68650, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  270. // 85062, 398951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  271. // 484013, 2520329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  272. // colum 0: A225588 descent sequences of length n
  273. // colum 1: first diffs of A225588
  274. case 95: // value of last part: A000000
  275. s = A.data()[n-1];
  276. break;
  277. // 1,
  278. // 1, 1,
  279. // 2, 2, 0,
  280. // 4, 4, 1, 0,
  281. // 9, 9, 5, 0, 0,
  282. // 23, 23, 18, 3, 0, 0,
  283. // 67, 67, 61, 26, 1, 0, 0,
  284. // 222, 222, 215, 145, 28, 0, 0, 0,
  285. // 832, 832, 824, 698, 293, 22, 0, 0, 0,
  286. // 3501, 3501, 3492, 3282, 2127, 496, 13, 0, 0, 0,
  287. // 16412, 16412, 16402, 16072, 13201, 5842, 716, 5, 0, 0, 0,
  288. // 85062, 85062, 85051, 84556, 78121, 50898, 14372, 890, 1, 0, 0, 0,
  289. // 484013, 484013, 484001, 483286, 469987, 383068, 183144, 31868, 962, 0, 0, 0, 0,
  290. default:
  291. cerr << "Invalid choice (exiting)." << endl;
  292. return 1;
  293. }
  294. st[ s ] += 1;
  295. #ifndef TIMING
  296. cout << setw(4) << ct << ": ";
  297. // print RGS:
  298. print_vec(" ", x, n, true );
  299. // print_vec(" ", A.m_, n, true );
  300. cout << setw(4) << s;
  301. // cout << setw(3) << A.num_zeros() << setw(3) << A.num_fixed_points();
  302. // cout << setw(4) << j;
  303. cout << endl;
  304. jjassert( A.OK() );
  305. #endif // TIMING
  306. }
  307. while ( (j=A.next()) );
  308. ulong sct = 0;
  309. for (ulong k=0; k<=n; ++k)
  310. {
  311. cout << st[k] << ", ";
  312. sct += st[k];
  313. }
  314. cout << endl;
  315. cout << " ct=" << ct; // total: OEIS sequence A225588
  316. cout << endl;
  317. jjassert( sct == ct );
  318. delete [] st;
  319. return 0;
  320. }
  321. // -------------------------
  322. /*
  323. Print triangle for stats q:
  324. OEIS example:
  325. q=0; for n in $(seq 0 13) ; do ./bin $n $q | grep ', $' ; done | nl -v0 -s': ' -w2 -n rz
  326. C++ comment:
  327. q=0; for n in $(seq 0 13) ; do ./bin $n $q | grep ', $' ; done | sed 's/^/\/\/ /; s/ $//;'
  328. Extract column c from stats q:
  329. q=0; c=0; echo $(for n in $(seq 0 13) ; do ./bin $n $q | grep ', $' ; done | cut -d, -f$((c+1))) | sed 's/ /, /g;'
  330. */
  331. /// Emacs:
  332. /// Local Variables:
  333. /// MyRelDir: "demo/comb"
  334. /// makefile-dir: "../../"
  335. /// make-target: "1demo DSRC=demo/comb/descent-rgs-stats-demo.cc"
  336. /// make-target2: "1demo DSRC=demo/comb/descent-rgs-stats-demo.cc DEMOFLAGS=-DTIMING"
  337. /// End: