/* ======= */
/* = ZS1 = */
/* ======= */
(
~zs1 ={|n, min=2, max=9|
var x, m, h, r, t, ret;
x=Array.newClear(n+1);
for(0,n,{|i| x[i] = 1});
x[0]=0;
x[1]=n;
m=1;
h=1;
ret = List[];
while({x[1] != 1}, {
if(x[h] == 2) {
m = m+1;
x[h] = 1;
h = h-1;
} {
r = x[h]-1;
t=(m-h+1);
x[h] = r;
while({t >= r}, {
h = h+1;
x[h]=r;
t = t-r;
});
if(t==0) {
m=h
} {
m=(h+1);
if(t>1) {
h=(h+1);
x[h] = t;
};
};
};
ret.add(x[1..m]);
});
ret.add([n]);
};
)
/* ======= */
/* = ZS2 = */
/* ======= */
(
~zs2 = {|argN, argMax|
var n; // The integer to partition
var x; // An array to store each new partition in;
var h; // The index of the last part of partition that is > 1
var m; // The number of parts in a partition
var j; // The index of the next part to be increased
var r; // A variable used to calculate the next m
var ret; // A list to store all partitions in, methods returns this;
var max; // The maximum value of any part (e.g. partion of 5 with a max of 3 can return [3,1,1] but not [4,1] or [5])
n = argN;
ret = List[];
if(argMax==nil) {
max = n;
} {
max = argMax;
};
//Fill the array with n *1
x = Array.fill(n, 1);
//Add the array as it forms the first partition
ret.add(x[0..n]);
//Alter x by setting the second element[1] to 2 and returning the subarray x[1..n]
x[1] = 2;
ret.add(x[1..n]);
h = 1;
m = n-1;
//Generate further partitions
while({x[1] != max},
{
if( (m-h) > 1) {
h = h+1;
x[h] = 2;
m = (m-1);
} {
j = (m-2);
while({x[j] == x[m-1]},
{
x[j] = 1;
j = (j-1);
}
);
h = (j+1);
x[h] = (x[m-1] +1);
r = (x[m] + ((x[m-1])*(m-h-1)));
x[m] = 1;
if( (m-h) > 1 ) {
x[m-1] = 1
};
m = (h + (r-1));
};
ret.add(x[1..m]);
}
);
ret
}
)