
#include "comb/dyck-gray2.h"

#include "fxtio.h"
#include "fxttypes.h"
#include "demo/nextarg.h"
#include "comb/comb-print.h"


//% Gray code for k-ary Dyck words.
//% Loopless algorithm, homogeneous two-close changes.

//#define TIMING // uncomment to disable printing


void
print_ivec(const char *bla, const int *x, ulong n)
// Print x[0,..,n-1] as vector, n is the number of elements in the set.
// If dfz is true then Dots are printed For Zeros.
{
    if ( bla )  cout << bla;

    cout << "[ ";
    for (ulong k=0; k<n; ++k)
    {
        int t = x[k];
        if ( t>=0 )  cout << '+';
        cout << t;
        if ( k<n-1 )  cout << " ";
    }
    cout << " ]";
}
// -------------------------

void
print_bvec(const char *bla, const bool *x, ulong n, bool dfz/*=false*/)
// Print x[0,..,n-1] as vector, n is the number of elements in the set.
// If dfz is true then Dots are printed For Zeros.
{
    if ( bla )  cout << bla;

    cout << "[ ";
    for (ulong k=0; k<n; ++k)
    {
        int t = x[k];
        if ( t!=0 )  cout << t;
        else         cout << (dfz?'.':'0');
        if ( k<n-1 )  cout << " ";
    }
    cout << " ]";
}
// -------------------------



int
main(int argc, char **argv)
{
    ulong m = 4;
    NXARG(m, "Number of ones in words.");
    ulong k = 3;
    NXARG(k, "k-ary Dyck words.");


    dyck_gray2 D(k, m);
    D.first();
    const ulong *c = D.data();

    ulong ct = 0;
    const ulong N = m*k;  // for printing as delta-sequence
    ulong ch = 0;
    do
    {
        ++ct;
#ifndef TIMING
        cout << setw(4) << ct << ":  ";
        print_sym_vec("  ", c, m);  // print 10 as A, 11 as B, etc.
        print_set1_as_deltaset("    ", c, m, N);  cout << "";

        cout << "    [ ";
        for (ulong j=1; j<=m; ++j)
        {
            const int s = D.s_[j];
            if ( s==0 )  { cout << " . "; continue; }
            if ( s>=0 )  cout << '+';
            cout << s << " ";
        }
        cout << "]";

//        print_vec("   e=", D.e_, m+1, 0);
//        print_bvec("   p=", D.p_+1, m, 1);
//        print_ivec("   s=", D.s_+1, m);
        cout << endl;
#endif

//        if ( ct > 56 )  break;
    }
    while ( (ch=D.next()) );

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

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

/*
 Timing:

 time ./bin 18 2
arg 1: 18 == m  [Number of ones in words.]  default=4
arg 2: 2 == k  [k-ary Dyck words.]  default=3
  ct=477638700
./bin 18 2  9.46s user 0.01s system 99% cpu 9.476 total
 ==> 477638700/9.46 == 50,490,348 per second

 time ./bin 13 3
arg 1: 13 == m  [Number of ones in words.]  default=4
arg 2: 3 == k  [k-ary Dyck words.]  default=3
  ct=300830572
./bin 13 3  5.08s user 0.01s system 99% cpu 5.087 total
 ==> 300830572/5.08 == 59,218,616 per second

 time ./bin 12 4
arg 1: 12 == m  [Number of ones in words.]  default=4
arg 2: 4 == k  [k-ary Dyck words.]  default=3
  ct=1882933364
./bin 12 4  28.85s user 0.03s system 99% cpu 28.905 total
 ==> 1882933364/28.85 == 65,266,321 per second

*/


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