
#include "comb/gray-cycle-leaders.h"
#include "bits/bittransforms.h"  // yellow_code()
#include "bits/bitcyclic-period.h"

#include "bits/graycode.h"
#include "bits/printbin.h"
#include "bits/bit2pow.h"
//#include "bits/bitsubset.h"
#include "bits/bitcount.h"

#include "bits/bitcyclic-minmax.h"

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

#include "jjassert.h"



//% Cycle leaders for gray permutation converted to necklaces

//#define CODE(x) blue_code(x)
#define CODE(x) yellow_code(x)  // default

void doit(ulong ldn, bool cq)
{
    gray_cycle_leaders L(ldn);

    ulong pn = ldn + 1;  // print precision (in bits)

    ulong len = L.cycle_length();
    ulong num = L.num_cycles();
//    cout << "  k =" << setw(2) << ldn << ":";
    cout << setw(3) << num << " cycles of length=" << setw(2) << len << "";
    cout << endl;

    pn = len;

    ulong ct = 0;
    do
    {
        ++ct;
//        ulong i = L.current_max();
        ulong i = L.current_min();
        print_bin(" L=  ", i, pn);

        ulong cn;
        cn = bit_cyclic_period(CODE(i));
        print_bin("  [ ", CODE(i), cn);  cout << " ] ";
        cout << " " << cn;
        cout << "  " << bit_count(CODE(i))/(BITS_PER_LONG/cn);
        cout << endl;
        if ( cq ) // print cycle:
        {
            for (ulong w=gray_code(i); w!=i; w=gray_code(w) )
            {
                print_bin(" --> ", w, pn);
                cn = bit_cyclic_period(CODE(w));
                print_bin("  [ ", CODE(w), cn);  cout << " ] ";

//                cout << " " << cn;
//                cout << "  " << bit_count(CODE(w))/(BITS_PER_LONG/cn);

                cout << endl;
            }
            cout << endl;
        }
    }
    while ( L.next() );
    cout
        << "  ldn=" << ldn << ":"
        << "  ct=" << ct
        << "  ==2**" << ld(ct) << endl;
}
// -------------------------

int
main(int argc, char **argv)
{
    ulong ldn = 6;
    NXARG(ldn, "necklace with ldn bits");
    jjassert( ldn );
    bool cq = 1;
    NXARG(cq, "Whether to print cycles");

    doit(ldn-1, cq);

    cout << endl;

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


/// Emacs:
/// Local Variables:
/// MyRelDir: "demo/comb"
/// makefile-dir: "../../"
/// make-target: "1demo DSRC=demo/comb/necklaces-via-gray-leaders-demo.cc"
/// make-target2: "1demo DSRC=demo/comb/necklaces-via-gray-leaders-demo.cc DEMOFLAGS=-DTIMING"
/// End:

