1
2 #include "comb/fact2perm.h"
3 // demo-include "comb/fact2perm.cc"
4 #include "comb/mixedradix.h"
5 #include "perm/reverse.h"
6 #include "perm/permcomplement.h"
7 #include "perm/perminvert.h"
8
9 #include "comb/mixedradix-modular-gray.h"
10 #include "comb/mixedradix-gslex.h"
11 #include "comb/mixedradix-gslex-alt.h"
12 #include "comb/mixedradix-subset-lex.h"
13 #include "comb/mixedradix-gray.h"
14 #include "comb/mixedradix-sl-gray.h"
15 #include "comb/mixedradix-endo.h"
16 #include "comb/mixedradix-endo-gray.h"
17
18 #include "comb/comb-print.h"
19
20 #include "comb/check-permgen.h"
21 #include "jjassert.h"
22
23 #include "fxttypes.h"
24 #include "nextarg.h" // NXARG()
25 #include "fxtio.h"
26
27
28 //% Generate all permutations from mixed radix (factorial) numbers.
29
30
31 int
main(int argc,char ** argv)32 main(int argc, char **argv)
33 {
34 ulong n = 4;
35 NXARG(n, "Number of elements to permute");
36 bool rq = 1;
37 NXARG(rq, "Whether to use rising factorial base.");
38 const bool dfz = true; // whether to print dots for zeros
39 const ulong n1 = n - 1;
40 bool iq = 0;
41 NXARG(iq, "Whether to generate inverse permutation for right columns (else reversed complement).");
42
43 mixedradix M(n1, rq); // default
44 // mixedradix_subset_lex M(n1, rq);
45 // mixedradix_sl_gray M(n1, rq);
46 // mixedradix_gray M(n1, rq);
47 // mixedradix_modular_gray M(n1, rq);
48 // mixedradix_gslex M(n1, rq);
49 // mixedradix_gslex_alt M(n1, rq);
50 // mixedradix_endo M(n1, rq);
51 // mixedradix_endo_gray M(n1, rq);
52 M.print_nines(" Nines: "); cout << endl;
53
54 const ulong *a = M.data(); // factorial number
55 ulong *ia = new ulong[n1]; // factorial number for inverse permutation
56
57 ulong *p = new ulong[n]; // permutation
58 ulong *ip = new ulong[n]; // inverse permutation
59
60 ulong *t = new ulong[n1]; // aux for testing
61
62 check_permgen C(n); C.first(p);
63
64 ulong ct = 0;
65 do
66 {
67 cout << " " << setw(3) << ct << ":";
68
69 print_mixedradix(" ", a, n1, dfz);
70 if ( rq ) rfact2perm(a, n, p);
71 else ffact2perm(a, n, p);
72 print_perm(" ", p, n, dfz);
73
74 cout << " ";
75
76
77 if ( iq )
78 {
79 make_inverse(p, ip, n);
80 print_perm(" ", ip, n, dfz);
81 if ( rq ) perm2rfact(ip, n, ia);
82 else perm2ffact(ip, n, ia);
83 print_mixedradix(" ", ia, n1, dfz);
84 }
85 else
86 {
87 make_complement(p, ip, n);
88 reverse(ip, n);
89 print_perm(" ", ip, n, dfz);
90 if ( ! rq ) perm2rfact(ip, n, ia);
91 else perm2ffact(ip, n, ia);
92 print_mixedradix(" ", ia, n1, dfz);
93 }
94
95
96 #if 1 // Testing that Xfact2perm() is inverse of perm2Xfact():
97 if ( rq ) perm2rfact(p, n, t);
98 else perm2ffact(p, n, t);
99 // print_mixedradix(" :: ", t, n1, dfz);
100 for (ulong j=0; j<n1; ++j) { jjassert(t[j]==a[j]); }
101 #endif
102
103 cout << endl;
104
105
106 ++ct;
107 jjassert( ! C.is_repeat() );
108 }
109 while ( M.next() );
110
111 delete [] ia;
112 delete [] p;
113 delete [] ip;
114 delete [] t;
115
116 return 0;
117 }
118 // -------------------------
119
120
121 /// Emacs:
122 /// Local Variables:
123 /// MyRelDir: "demo/comb"
124 /// makefile-dir: "../../"
125 /// make-target: "1demo DSRC=demo/comb/fact2perm-demo.cc"
126 /// make-target2: "1demo DSRC=demo/comb/fact2perm-demo.cc DEMOFLAGS=-DTIMING"
127 /// End:
128
129