
#include "comb/perm-involution.h"

#include "perm/permq.h"
#include "comb/comb-print.h"
#include "perm/printcycles.h"

#include "comb/fact2perm.h"

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


//% Generate all involutions (self-inverse permutations).

//#define TIMING // uncomment to disable printing


int
main(int argc, char **argv)
{
    ulong n = 5;
    NXARG(n, "Self-inverse permutations of n elements (n>=1).");
    bool dfz= true; // whether to print dots for zeros
    jjassert( n>=1 );

    perm_involution P(n);
    ulong ct = 0;

#ifdef TIMING
    while ( P.next() )  { ++ct; }

#else

    const ulong *x = P.data();
//    ulong it[64]; // inversion table
    do
    {
        cout << setw(4) << ct << ":";
        ++ct;

        P.print("  ", dfz);

//        perm2rfact(x, n, it);
//        print_vec("  ", it, n-1, dfz);

        cout << "    ";  print_cycles(x, n);

        cout << endl;

        jjassert( is_involution(x, n) );
    }
    while ( P.next() );

#endif
    cout << " ct=" << ct << endl;

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

/*
Timing:

  time ./bin 17
arg 1: 17 == n  [Self-inverse permutations of n elements.]  default=5
 ct=211799311
./bin 17  3.96s user 0.00s system 99% cpu 3.971 total
 ==> 211799311/3.96 == 53,484,674 per second
*/

/*
Timing: (AMD Phenom II X4 945 3000MHz)

 time ./bin 17 1
arg 1: 17 == n  [Self-inverse permutations of n elements.]  default=5
 ct=211799311
./bin 17 1  2.91s user 0.00s system 99% cpu 2.915 total
 ==> 211799311/2.91 == 72,783,268 per second

*/

/*
BENCHARGS=17
*/


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


