vote up 1 vote down
star

I'm looking for a way of generating all permutations of three digits (actually xyz) that sum to the same value.

For example:

n = 1:

0 0 0

n = 2:

0 0 1
0 1 0
1 0 0

n = 3:

0 1 1
1 0 1
1 1 0
0 0 2
0 2 0
2 0 0

n = 4:

1 1 2
...

Ideally I need a way of mapping indices to the three digits in a unique way such that I can take an index up to the associated triangle number n * (n + 1) / 2 and find the same three indices every time.

Can anyone point me in the right direction? It's quite some time since I've worked with sequences and I'm a little rusty.

flag
The 'generating-functions' tag is quite unrelated. – Mariano Suárez-Alvarez Dec 21 at 16:06
I removed the generating-functions tag. – Michael Lugo Dec 21 at 16:11
For enumeration problems of this kind it is often of interest to have the consecutive items in the list (including between the last and first) be "near each other." This type enumeration is called a "Gray code," for Frank Gray who carried out an enumeration of this kind for the binary sequences of length n. For the binary sequences the idea was to have consecutive sequences have Hamming distance 1 between them. So the Gray code for this case is a Hamiltonian circuit on the n-cube. – Joseph Malkevitch Dec 21 at 18:39

2 Answers

vote up 3 vote down

The answer is detailed (along with MATLAB code) at

http://blog.eqnets.com/2009/10/06/a-graded-lexicographic-index-part-1/

and successive posts. Use the MATLAB function "lookup" to produce the graded lex order.

link|flag
vote up 3 vote down

Your question is how to list the ways to multichoose the positions of $n$ balls in 3 boxes. You could more generally list the ways to multichoose the positions of $k$ balls in $n$ boxes.

The clearest theoretical answer is given by the "stars and bars" construction. Multiset coefficients and the stars and bars construction are explained very nicely in Wikipedia. Here is a Python code inspired by the stars-and-bars bijection between multiset choices and ordinary subset choices.

def multichoose(n,k):
    if k < 0 or n < 0: return "Error"
    if not k: return [[0]*n]
    if not n: return []
    if n == 1: return [[k]]
    return [[0]+val for val in multichoose(n-1,k)] + \
        [[val[0]+1]+val[1:] for val in multichoose(n,k-1)]

Evaluate multichoose(3,4) and see what you get!

link|flag

Your Answer

Get an OpenID
or

Not the answer you're looking for? Browse other questions tagged or ask your own question.