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

#include "bits/bitlow.h"
#include "bits/printbin.h"
#include "perm/permq.h" // is_valid_permutation()

#include "fxtiomanip.h"
#include "jjassert.h"
#include "fxttypes.h"  // ulong

#include "demo/nextarg.h"  // ulong



//% Representation in radix(-2).
// see HAKMEM item 128.


int
main(int argc, char **argv)
{
    ulong ldn = 5;
    NXARG(ldn, "Number of bits");
    ulong n = 1UL<<ldn;
    int pn = (int)ldn + 2;
    ulong *f = new ulong[n];

    ulong gg = 0;
    cout << setw(3) << "  k :";
    cout << setw(pn+2) << "bin(k)";
    cout << "  ";
    cout << setw(pn+2) << "m=bin2neg(k)";
    cout << "  ";
    cout << setw(pn+2) << "g=gray(m)";
    cout << setw(3+2) << "   dec(g)";
    cout << endl;

    for (ulong k=0; k<n; ++k)
    {
        ulong m = bin2neg(k);
        ulong g = gray_code(m);
        ulong bg = neg2bin(g);
        f[k] = bg;
//        if ( g & (g>>1) )  goto next;  // only Fibonacci words

        cout << setw(3) << k;
        print_bin(":  ", k, pn);
        print_bin("    ", m, pn);
        print_bin("    ", g, pn);

//        ulong zp = ((g&0xaaaaaaaaUL) << 1) ^ ((g&0x55555555) >> 1) ^ (g&1);
//        print_bin("    ", zp, pn);

//        print_bin("  ",g^gg,pn);  // negbin ruler function
//        cout << "%" << 1+lowest_one_idx(g^gg) << "%";

//        cout << " = " << setw(3) << (g^gg);
//        print_bin("    ", gray_code(bin2neg(-k)), pn);
//        print_bin("    ", bg, pn);
        cout << "    " << setw(4) << bg;

        if ( is_valid_permutation(f,k+1) )  cout << " <= " << k;

//        if ( m==k )  cout << " %";

        cout << endl;

//    next:
        jjassert( neg2bin(m) == k );
        gg = g;
    }

    // sequence of fixed points:
//    for (ulong k=0; k<n/2; ++k)
//    {
//        ulong fx = negbin_fixed_point(k);
//        cout << setw(4) << k << ": ";
//        print_bin("    ", fx, pn);
//        cout << " == " << setw(4) << fx;
//        cout << endl;
//    }

    cout << endl;

    delete [] f;

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

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

