
#include "comb/perm-rev2.h"

#define PERM_STAR_WITH_INVERSE  // make sure inverse is computed
#include "comb/perm-star.h"

#include "comb/comb-print.h"

#include "comb/check-permgen.h"

#include "fxtio.h"
#include "demo/nextarg.h"
#include "fxttypes.h"
#include "jjassert.h"


//% Inverse star transposition permutations via permutations by prefix reversions.

//#define TIMING // uncomment to disable printing



int
main(int argc, char **argv)
{
    ulong n = 4;
    NXARG(n, "Number of elements to permute n>0");
    jjassert( n>0 );
    bool dfz= true; // whether to print dots for zeros


#ifndef TIMING
    perm_star S(n);  S.first();
    const ulong *si = S.invdata();
#endif

    perm_rev2 P(n);  P.first();
    const ulong *r = P.data();

    ulong *x = new ulong[n];
    for (ulong k=0; k<n; ++k)  x[k] = k;
    ulong ct = 0;
    ulong i0 = 0;  // position of element zero
    do
    {
        ++ct;
        ulong i1 = r[0];
        swap2(x[i0], x[i1]);
#ifndef TIMING
        cout << setw(4) << ct << ":";
        print_perm("    ", x, n, dfz);
        cout << "    " << "(" << i0 << ", " << i1 << ")";
        P.print("    ", dfz);
        cout << endl;
        for (ulong j=0; j<n; ++j)  jjassert( si[j]==x[j] );
        S.next();
#endif
        i0 = i1;
    }
    while ( P.next()!=n );


    cout << endl;
    cout << " ct=" << ct << endl;
    cout << endl;

    delete [] x;

    return 0;
}
// -------------------------

/*
Timing:

 time ./bin 13
./bin 13  40.67s user 0.07s system 100% cpu 40.739 total
 ==> 13!/40.97 == 151,989,768 per second

*/

/// Emacs:
/// Local Variables:
/// MyRelDir: "demo/comb"
/// makefile-dir: "../../"
/// make-target: "1demo DSRC=demo/comb/perm-star-inv-demo.cc"
/// make-target2: "1demo DSRC=demo/comb/perm-star-inv-demo.cc DEMOFLAGS=-DTIMING"
/// End:

