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