Partitions of an integer

Michael J. Fromberger Michael.J.Fromberger at Clothing.Dartmouth.EDU
Sun Jul 25 20:12:57 CEST 2004


In article <pNvMc.381$KU.186 at animal.nntpserver.com>,
 Nick J Chackowsky <mediocre_person at hotmail.com> wrote:

> Wrote a python script to find the partitions of an integer (a list of 
> all the ways you can express n as a sum of integers). For example, the 
> partitions of 5 are
> 5
> 4+1
> 3+2
> 2+2+1
> 3+1+1
> 2+1+1+1
> 1+1+1+1+1
> 
> My method, however, generates plenty of duplicates (note the if 
> statement to catch them). Generating the 15 partitions of 7, for 
> example, also generates 19 duplicates. Can someone spot a way to improve 
> or eliminate the duplicates?
> 
> Nick.

I propose the following recursive solution:

  def sorted(tpl):
      copy = list(tpl)[:] ; copy.sort()
      return tuple(copy)
  
  def nat_partitions(n, mem = {}):
      assert n > 0
      
      if mem.has_key(n):
         return mem[n]
      
      parts = {}
      for b in range(1, n):
          for p in nat_partitions(n - b):
              parts[sorted(p + (b,))] = True
      
      mem[n] = parts.keys() + [(n,)]
      return mem[n]

>>> from pprint import pprint
>>> pprint(nat_partitions(7))
[(1, 1, 1, 1, 3),
 (1, 1, 2, 3),
 (3, 4),
 (1, 3, 3),
 (1, 2, 4),
 (1, 1, 1, 2, 2),
 (1, 1, 1, 1, 1, 2),
 (1, 1, 1, 1, 1, 1, 1),
 (1, 1, 1, 4),
 (1, 1, 5),
 (2, 2, 3),
 (2, 5),
 (1, 2, 2, 2),
 (1, 6),
 (7,)]

Certainly the algorithm is simple enough, though there is a certain 
amount of thrashing between lists and tuples doing it this way.  But, 
with the memoization, it performs reasonably well.

-M

-- 
Michael J. Fromberger             | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/  | Dartmouth College, Hanover, NH, USA



More information about the Python-list mailing list