generating canonical list of tuples?
aleax at aleax.it
Fri Jan 4 09:02:19 EST 2002
"Joshua Muskovitz" <joshm at taconic.net> wrote in message
news:3c34cafa_2 at corp.newsgroups.com...
> Here's what I'm trying to do...
> create "magicFunction(limit, dimension)" to return a list of tuples. Each
> tuple contains exactly "dimension" elements, all positive integers. The
> of these elements must be less than or equal to "limit".
> for example, magicFunction(5,3) should return:
> [ (1,1,1), (1,1,2), (1,1,3), (1,2,1), (1,2,2), (1,3,1), (2,1,1), (2,1,2),
> (2,2,1), (3,1,1) ]
> The order of the resulting tuples is unimportant.
OK, quite clear.
> If "dimension" is a fixed number, this is easy. In the case where
> But (and here is the REAL question)... how does one do this when
> is a variable?
Think "counting in a variable base" -- it's often a good mindset in
such 'enumeration problems'. In counting we increment each digit as
far as possible, then when the digit would overflow we reset it to
the minimum value and proceed to the next most significant digit.
Here, a 'digit overflows' when the total reaches the limit, so...:
def magicFunction(limit, dimension):
if limit < dimension: return 
current = *dimension
results = [tuple(current)]
return reduce(operator.add, current)
index = 0
while index < dimension:
if total(current) < limit:
current[index] += 1
break # exit inner loop, continue outer loop
elif current[index] > 1:
current[index] = 1
index += 1
else: return results
Rather than recomputing the total() each time, you could also
maintain it incrementally. This also looks like a good
candidate to make into a simple-generator, by just changing
the .append (and the first assiment to results) into yield
statements and making the return statements expressionless --
but that, obviously, wouldn't change the algorithm, just package
it up in a potentially more usable way.
More information about the Python-list