
#include "comb/combination-revdoor.h"

#include "aux0/binomial.h"
#include "comb/comb-print.h" // print_set_as_deltaset()

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

#include "fxtio.h"

//% Generating all combinations in minimal-change order: revolving door algorithm.

//#define TIMING // uncomment to disable printing


int
main(int argc, char **argv)
{
    ulong n = 7;
    NXARG(n, "Combination (n choose k) in minimal-change order: n>=1");
    ulong k = 4;
    NXARG(k, "(n choose k):  1<=k<=n");

    if ( (k>n) || (n==0) || (k==0) )  { return 1; }

    combination_revdoor C(n, k);

    ulong ct = 0;
    do
    {
#ifndef TIMING
        cout << setw(3) << ct << ":    ";
        C.print_set("  ");
        C.print_deltaset("    ");
        cout << endl;
#endif // TIMING
        ++ct;
    }
    while ( C.next() );

    ulong bnk =  binomial(n, k);
    cout << "binomial(" << n << ", " << k << ")=" << bnk << endl;
    jjassert( bnk==ct );
    cout << endl;

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

// for n in $(seq 1 10); do for k in $(seq 1 $n); do ./bin $n $k || break 2; done; done

/*
Timing:
 %  time ./bin 32 20
arg 1: 32 == n  [(n choose k): n>=1]  default=7
arg 2: 20 == k  [(n choose k):  1<=k<=n]  default=4
arg 3: 0 == rq  [Option: print in reverse order]  default=0
binomial(32, 20)=225792840
./bin 32 20  1.90s user 0.02s system 99% cpu 1.929 total
 ==> 117,051,757 comb/sec

 %  time ./bin 32 12
arg 1: 32 == n  [(n choose k): n>=1]  default=7
arg 2: 12 == k  [(n choose k):  1<=k<=n]  default=4
arg 3: 0 == rq  [Option: print in reverse order]  default=0
binomial(32, 12)=225792840
./bin 32 12  1.23s user 0.02s system 99% cpu 1.247 total
 ==> 181,068,837 comb/sec
*/

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

