# Re: [sc-users] non random integer partition

I needed integer partitioning a few years ago, so implemented the z1 algorithm, for larger numbers it got pretty slow so I also implemented it in C, which I used to cache results to file, and then read, but you may also be able to call and parse it using .unixCmd

// SuperCollider
~zs1 ={|n=5|
var x, m, h, r, t, ret;
x=Array.fill(n, 1);
x[0]=n;
m=0;
h=0;
ret = List[n];

while({x[0] != 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;
};

//C

#include <stdlib.h>
#include <stdio.h>

void zs1(size_t n, FILE *fd)
{
size_t i, m, h, r, t;
size_t *x;

x = malloc(sizeof(*x)*(n+1));

for (i = 1; i <= n; i++)
x[i] = 1;

x[1] = n;
m = 1;
h = 1;
fprintf(fd,"%zd\n",x[1]);

while (x[1] != 1) {
if (x[h] == 2) {
m = m + 1;
x[h] = 1;
h = h - 1;
} else {
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;
} else {
m = h + 1;
if (t > 1) {
h = h + 1;
x[h] = t;
}
}
}

for (i = 1; i <= m; i++)
fprintf(fd,"%zd ",x[i]);
fprintf(fd,"\n");
}

free(x);
}

int main(int argc, char**argv)
{

int first_arg = 0;
if(argc > 1) {
first_arg = atoi(argv[1]);
} else {
printf("must pass integer as argument\n");
return 0;
}

// printf("Partitioning: %d\n", first_arg);

zs1(first_arg, stdout);
return 0;
}

On 20 December 2015 at 22:53, Daniel Mayer wrote:

Am 20.12.2015 um 13:42 schrieb simdax <simoncornaz@xxxxxxxxx>:

Hello,

nop MagicWindow, what I want is something like
5 => (1, 1, 1, 1, 1) , (2, 1, 1, 1),  (2, 2, 1), (3, 1, 1), (3, 2), (4, 1),
(5)

And as always, thank you Daniel, the enum tool is very useful :D !

But, in reality, my question stays : is it possible to "translate" the first
python func, which seems pretty similar to your function "g" in tutorial,
Daniel

The python code does something different from SC's built-in method 'partitions' !
The latter gives out *ordered partitions* in mathematical sense
wheras the python code only regards *unordered partitions* in mathematical sense -

in both cases and when results are additionally ascending (ordered numbers) they represent
the *unordered* partition in mathematical sense, where order doesn't count.

But of course you can also write this recursively in SC
(I take a recursion start of 1 instead of 0 here, as it's more comfortable):

~p = { |n|
var ps;
(n==1).if { [[1]] }{
ps = ~p.(n-1).copy;
ps.collect([1]++_) ++ (
ps.select { |p| (p.size<2) or: { p[1]>p[0] } }
.collect { |p| [p[0]+1] ++ p[1..] }
)
}
}

~p.(5)

The code in the miSCellaneous example with Functions g and h additionally regards
ordering and size of the partition, which, when summing over all sizes
results in finding all ordered partitions.

Regards

Daniel

-----------------------------
www.daniel-mayer.at
-----------------------------