#if !defined HAVE_PARTITION_GEN_H__
#define      HAVE_PARTITION_GEN_H__


#include "fxttypes.h"


class partition_gen
// Integer partitions of x into supplied values pv[0],...,pv[n-1].
// pv[] defaults to [1,2,3,...,x]
{
public:
    ulong ct_;  // Number of partitions found so far
    ulong n_;   // Number of values
    ulong i_;   // level in iterative search

    long *pv_;  // values into which to partition
    ulong *pc_; // multipliers for values
    ulong pci_; // temporary for pc_[i_]
    long *r_;   // rest
    long ri_;   // temporary for r_[i_]
    long x_;    // value to partition

public:
    partition_gen(ulong x, ulong n=0, const ulong *pv=0)
    {
        if ( 0==n )  n = x;
        n_ = n;
        pv_ = new long[n_+1];
        if ( pv )  for (ulong j=0; j<n_; ++j)  pv_[j] = pv[j];
        else       for (ulong j=0; j<n_; ++j)  pv_[j] = j + 1;
        pc_ = new ulong[n_+1];
        r_  = new long[n_+1];
        init(x);
    }

    void init(ulong x)
    {
        x_ = x;
        ct_ = 0;
        for (ulong k=0; k<n_; ++k)  pc_[k] = 0;
        for (ulong k=0; k<n_; ++k)  r_[k] = 0;
        r_[n_-1] = x_;
        r_[n_] = x_;
        i_ = n_ - 1;
        pci_ = 0;
        ri_ = x_;
    }

    ~partition_gen()
    {
        delete [] pv_;
        delete [] pc_;
        delete [] r_;
    }

    ulong next();  // generate next partition
    ulong next_func(ulong i);  // aux

    ulong count(ulong x);  // count number of partitions
    ulong count_func(ulong i);  // aux

    void print()  const;
    void print2()  const;
    bool  check(ulong i=0)  const;
};
// -------------------------


#endif  // !defined HAVE_PARTITION_GEN_H__
