#include <iostream>
class DividePatternGeneratorException {};
class DividePatternGenerator
{
private: /* private fields */
int* _list;
int _size;
int _division;
int _min;
int _max;
int _count;
private: /* private constructors */
DividePatternGenerator();
private: /* private methods */
void init()
{
if(
_size < 2 ||
_division < 2 ||
_size < _division ||
_size < _min * _division ||
_max < _min ||
_size < _max + _min * ( _division - 1 ) )
{
throw DividePatternGeneratorException();
}
_list = new int[_division];
for( int i = 0; i < _division; i++ )
{
_list[i] = 0;
}
}
public: /* public constructors */
DividePatternGenerator( int size, int division, int minsize, int maxsize )
: _size( size ), _division( division ), _min( minsize ), _max( maxsize ), _count( 0 )
{
init();
}
DividePatternGenerator( int size, int division )
: _size( size ), _division( division ), _min( 1 ), _max( size - division + 1 ), _count( 0 )
{
init();
}
DividePatternGenerator( int size )
: _size( size ), _division( 2 ), _min( size / 2 ), _max( size - 1 ), _count( 0 )
{
init();
}
public: /* public destructor */
~DividePatternGenerator()
{
delete[] _list;
}
public: /* public methods */
int length() const
{
return _division;
}
int size() const
{
return _size;
}
int count() const
{
return _count;
}
const int* list() const
{
return _list;
}
const int* next()
{
int n, d, p;
bool f;
if( !_count )
{
_list[0] = _min;
p = 1;
d = _division - 1;
n = _size - _min;
f = false;
}
else
{
p = _division - 2;
d = 2;
n = _list[p] + _list[p + 1];
f = true;
}
for( ;; )
{
if( d == 1 )
{
if( n <= _max )
{
_list[p] = n;
n = 0;
d = 0;
_count++;
break;
// OK
// exit loop
}
else
{
d++;
p--;
n += _list[p];
f = true;
}
}
else
{
int m;
if( f )
{
m = _list[p] + 1;
f = false;
}
else
{
m = _list[p - 1];
}
if( m * d > n )
{
if( !p )
{
_count = 0;
_list[0] = _min;
p = 1;
d = _division - 1;
n = _size - _min;
// all pattern had gone
// reset pattern
}
else
{
d++;
p--;
n += _list[p];
f = true;
}
}
else
{
_list[p] = m;
n -= m;
d--;
p++;
}
}
}
return _list;
}
};
int main()
{
try
{
DividePatternGenerator gen( 10, 5 );
std::cout << "10個を5分割するパターンのリストを作る" << std::endl;
std::cout << "size: " << gen.size() << std::endl;
for( int j = 0; j < 10; j++ )
{
const int* list = gen.next();
std::cout << "[" << gen.count() << "] ";
for( int i = 0; i < gen.length(); i++ )
{
std::cout << list[i] << " ";
}
std::cout << std::endl;
}
std::cout << "* * * * * * * * * * * * * *" << std::endl;
DividePatternGenerator gen2( 10, 3 );
std::cout << "10個を3分割するパターンのリストを作る" << std::endl;
std::cout << "size: " << gen2.size() << std::endl;
for( int j = 0; j < 10; j++ )
{
const int* list = gen2.next();
std::cout << "[" << gen2.count() << "] ";
for( int i = 0; i < gen2.length(); i++ )
{
std::cout << list[i] << " ";
}
std::cout << std::endl;
}
}
catch( DividePatternGeneratorException& ex )
{
std::cout << "Exception" << std::endl;
}
return 0;
}