Here is some idea.
If I'm not mistaken the number of the arrays is 2
N-1
and the arrays map to bit patterns codding integers form 0
to 2
N-1
-1
as follows:
I'll show an example for N = 4
The first array is all ones. Imagine every bit in the bit pattern corresponds to the boundary between two array cells
1 1 1 1 <- array elements
| | | <- sections
0 0 0 <- bit pattern
Every 1 in the bit pattern means merging two neighbouring cells
1 (1+1) 1 <- array elements (1 2 1)
| | | <- sections
0 1 0 <- bit pattern
1 (1+1+1) <- array elements (1 3)
| | | <- sections
0 1 1 <- bit pattern
(1+1) (1+1)<- array elements (2 2)
| | | <- sections
1 0 1 <- bit pattern
(1+1+1+1) <- array elements (4)
| | | <- sections
1 1 1 <- bit pattern
To enumerate all arrays you can generate integers from 0
to 2
N-1
-1
and for every bit pattern you get, generate the corresponding array. It might be helpful to convert the integer to the string of zeros and ones of length N-1
. You decode the pattern as follows:
First cell contains 1
initially. Going through the pattern from left to right, for every bit, if it's 1
add 1
to the current cell, if it's 0
create new cell containing 1
.
The pattern 1 1 0 0 1 0 1
for N = 8
would be decoded to an array
(3 1 2 2)
Here is some C++ code without argument validation and processing the pattern from right to left. It just changes the order of arrays produced and is simpler to code.
std::vector<std::vector<int> > generateArrays(unsigned int N)
{
//validate the argument before processing
// N > 0 and N <= numeric_limits<unsigned int>::digits
unsigned int numOfArrays = (1U << (N-1));
std::vector<std::vector<int> > result(numOfArrays);
for(unsigned int i = 0; i < numOfArrays; ++i)
{
result[i].push_back(1);
unsigned int mask = 1U;
while(mask < numOfArrays)
{
if((i & mask) != 0)
{
result[i].back()++;
}
else
{
result[i].push_back(1);
}
mask <<= 1;
}
}
return result;
}