
#include "bits/bitlex.h"
#include "bits/printbitset.h"

#include "fxttypes.h"
#include "fxtiomanip.h"
#include "bits/printbin.h"
#include "bits/bitsperlong.h"

//#include "bits/graycode.h"
//#include "bits/bitcount.h"

#include "demo/nextarg.h"


//% Generating binary words in subset-lexicographic order.

//#define TIMING // uncomment to disable printing

int
main(int argc, char **argv)
{
    ulong n = 5;
    NXARG(n, "n-bit binary words");
    ulong m = 1UL<<n;
    bool bq = 0;
    NXARG(bq, "Whether to also print backwards list");
    // Note: with benchmark: whether to go backwards
    const ulong rq = n;


#ifndef TIMING
    ulong x = 1UL<<(n-1);  // first subset
    ulong ct = 0;
    do
    {
        ++ct;
        cout  << setw(4) << ct << ":";
        print_bin("  ", x, n);
        cout << "  = " << setw(2) << x;
//        cout << "   b=" << setw(2) << bit_count(x);
        print_bit_set("  ", x, rq);
        cout << endl;
    }
    while ( (x=next_lexrev(x)) );


    cout << endl;

    if ( bq )
    {
//        cout << " ... and backward (fixed point marked with '*'):" << endl;
        ct = 1;
        while ( (x = prev_lexrev(x)) < m )
        {
            cout  << setw(4) << ct << ":";
            print_bin("  ", x, n);
            cout << "  = " << setw(2) << x;
//            cout << "   b=" << setw(2) << bit_count(x);

//            if ( is_lexrev_fixed_point(x) )  cout << " *";  else  cout << "  ";

            print_bit_set("  ", x, rq);

//            print_bin("  ", negidx2lexrev(ct), n+1);  // == x
//            ulong z = x ^ next_lexrev(x);
//            print_bin("  ", z, n+1);
            ++ct;
            cout << endl;
        }
    }
#else

    if ( !bq )
    {
        cout << "forward:" << endl;
        ulong x = (1UL<<n)-1;  while ( (x=next_lexrev(x)) )  { ; }
    }
    else
    {
        cout << "backward:" << endl;
        ulong x = 0;  while ( (x=prev_lexrev(x))<m )  { ; }
    }
#endif

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

/*
Timing:

 time ./bin 32 0
arg 1: 32 == n  [n-bit binary words]  default=5
arg 2: 0 == bq  [Whether to also print backwards list]  default=0
forward:
./bin 32 0  15.66s user 0.03s system 100% cpu 15.689 total
 ==> 2^32/15.66 == 274,263,556 per second

 time ./bin 32 1
arg 1: 32 == n  [n-bit binary words]  default=5
arg 2: 1 == bq  [Whether to also print backwards list]  default=0
backward:
./bin 32 1  16.93s user 0.00s system 99% cpu 16.937 total
 ==> 2^32/16.93 == 253,689,739 per second

BENCHARGS=32 0
BENCHARGS=32 1

*/


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

