
#include "comb/partition.h"

#include "fxttypes.h"

#include "jjassert.h"
#include "nextarg.h"

#include "fxtio.h"

//% Generate all integer partitions, iterative algorithm.

//#define TIMING // uncomment to disable printing

int
main(int argc, char **argv)
{
    ulong n = 6;
    NXARG(n, "Partitions of n");
    bool sq = 0;
    NXARG(sq, "Whether to print cumulative sums");
    partition P(n);

    ulong ct = 0;

#ifdef TIMING
    if ( !sq ) // here: whether forward or backward
    {
        cout << "forward:" << endl;
        P.first();
        do  { ++ct; }  while ( P.next() );
    }
    else
    {
        cout << "backward:" << endl;
        P.last();
        do  { ++ct; }  while ( P.prev() );
    }
#else // TIMING

    do
    {
#if 0  // just count certain partitions:

//        if ( P.num_of(1) == 0 )  { ct += 1; }  // OEIS sequence A002865
//        if ( P.num_of(2) == 0 )  { ct += 1; }  // A027336

//        if ( P.num_of(1) == 0 )  { ct += P.num_of(3); } // A182713
//        if ( P.num_of(1) == P.num_of(2) )  { ct += 1; } // A174455
//        if ( P.num_of(1) != P.num_of(2) )  { continue; } // A174455 (show partitions)

//        if ( P.num_of(1) != 0 )  continue;
//        { ulong m=2; while ( P.num_of(m) == 0 )  { ++m; };  ct += m; }

//        { ulong m=1; while ( P.num_of(m) == 0 )  { ++m; }; ct += (n-m*P.num_of(m)); }

        continue;
#endif

#if 1
        cout << "    #" << setw(2) << ct << ": ";
//        cout << " [" << P.num_parts() << "]  ";
//        cout << " [" << P.num_sorts() << "]  ";
        cout << setw(4) << P.n_;
        cout << " == ";  P.print_long();
        cout << "  ==  ";  P.print();
        cout << endl;

        if ( sq )
        {
            cout << "       sums: ";
            for (ulong k=2; k<=n; ++k)  cout << setw(7) << P.s_[k];
            cout << endl;
            cout << endl;
        }
        jjassert( P.OK() );

#else

    for (ulong k=1; k<=n; ++k)
    {
        ulong c = P.data()[k];
        for (ulong j=0; j<c; ++j)
            cout << "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[k] << " ";
    }
    cout << endl;

#endif

        ++ct;
    }
    while ( P.next() );
#endif // TIMING


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

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

/*
Timing:

 time ./bin 110 0
forward:
  ct=607163746
./bin 110 0  3.02s user 0.00s system 99% cpu 3.032 total
 ==> 607163746/3.02 == 201,047,598 per second

// line  q = (z>=i ? z/i : 0);  :
 time ./bin 100 1
backward:
  ct=190569292
./bin 100 1  2.70s user 0.00s system 99% cpu 2.705 total
 ==> 190569292/2.70 == 70,581,219 per second

// line  q = z/i;  :
 time ./bin 100 1
backward:
  ct=190569292
./bin 100 1  3.03s user 0.01s system 99% cpu 3.055 total
 ==> 190569292/3.03 == 62,894,155 per second

*/

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

 time ./bin 110 0
arg 1: 110 == n  [Partitions of n]  default=6
arg 2: 0 == sq  [Whether to print cumulative sums]  default=0
forward:
  ct=607163746
./bin 110 0  2.51s user 0.00s system 99% cpu 2.518 total
 ==> 607163746/2.51 == 241,897,906 per second

 time ./bin 100 1
arg 1: 100 == n  [Partitions of n]  default=6
arg 2: 1 == sq  [Whether to print cumulative sums]  default=0
backward:
  ct=190569292
./bin 100 1  1.08s user 0.00s system 99% cpu 1.080 total
 ==> 190569292/1.08 == 176,453,048 per second

*/


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

