
#include "comb/mixedradix-naf.h"

#include "aux1/copy.h" // fill()

#include "nextarg.h" // NXARG()
#include "fxttypes.h"
#include "fxtalloca.h"
#include "fxtio.h"

#include "jjassert.h"

#include <cstdlib>  // strtoul()

//% Mixed radix non-adjacent forms (NAF).


//#define TIMING // uncomment to disable printing

int
main(int argc, char **argv)
{
    ulong n = 6;
    NXARG(n,"Number of digits");

    ulong rr = 3;
    NXARG(rr, "Base (radix) of digits (0==>falling factorial, 1==>rising factorial)");

    ALLOCA(ulong, r, n);
    fill(r, n, rr);
    RESTARGS("Optionally supply radix for all digits (rr ignored)");
    if ( argc>3 )  jjassert( argc == (int)n+3 );
    for (ulong k=3;  k<(ulong)argc; ++k)  r[k-3] = strtoul(argv[k], 0, 10);

    mixedradix_naf M(n, rr, (argc>3? r:0) );
    M.print_nines("Nines: ");
    cout << endl;

    ulong ct = 0;
//    M.last();
    do
    {
#ifndef TIMING
        cout << " " << setw(4) << ct << ":  ";
        M.print("    ", true );
        cout << "  " << M.pos();
        cout << endl;

        const ulong *x = M.data();
        for (ulong j=1; j<n; ++j)  jjassert( (x[j-1]==0) || (x[j]==0) );
#endif // TIMING
        ++ct;
    }
    while ( M.next() );
//    while ( M.prev() );

    jjassert( ct == 85 );

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

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

/*
Timing: (AMD Phenom II X4 945 3000MHz)

 time ./bin 42 2 ## binary is worst case (Fibonacci strings)
 ct=701408733
./bin 42 2  3.34s user 0.00s system 99% cpu 3.344 total
 ==> 701408733/3.34 == 210,002,614 per second
./bin 42 2  3.37s user 0.00s system 99% cpu 3.375 total  // with array

./bin 42 2  3.68s user 0.00s system 99% cpu 3.678 total  // prev() with pointers


 time ./bin 24 4
 ct=727060321
./bin 24 4  2.92s user 0.00s system 99% cpu 2.920 total
 ==> 727060321/2.92 == 248,993,260 per second
./bin 24 4  3.15s user 0.00s system 99% cpu 3.154 total  // with array

./bin 24 4  2.91s user 0.00s system 99% cpu 2.912 total  // prev() with pointers


 time ./bin 17 0  ## falling factorial
 ct=997313824
./bin 17 0  2.95s user 0.00s system 99% cpu 2.954 total
 ==> 997313824/2.95 ==338,072,482 per second
./bin 17 0  2.74s user 0.00s system 99% cpu 2.745 total  // with array

./bin 17 0  2.95s user 0.00s system 99% cpu 2.952 total  // prev() with pointers

*/

/*

BENCHARGS=42 2
BENCHARGS=24 4
BENCHARGS=17 0

*/

/*
OEIS sequences:

Falling factorial numbers: A000085 (self-inverse permutations, with offset 1)
%  for n in $(seq 1 11); do ./bin $n 0 | grep ct= ; done
(same for rising factorial numbers)

Radix 2: A000045 (Fibonacci numbers)
Radix 3: A028859
Radix 4: A125145
Radix 5: A086347

*/

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

