Daniel Fischer daniel.is.fischer at web.de
Sat Aug 29 12:39:18 EDT 2009

```Am Samstag 29 August 2009 17:43:02 schrieb I. J. Kennedy:
> The following function finds all the partitions of an integer that are
> It works, but I'm not happy with it--seems too complex.  Is there a
> way to implement this?
>
> -- parts n finds all the partitions of n having unique parts
> -- helper function parts' n r m   finds partitions of  n  from a set
> r  of remaining possible parts,
> --  with a minimum part of  m.
>
> parts n = parts' n [1..n] 1  where
>  parts' 0 _ _ = [[]]                  -- there's always one way ([])
> to get a sum of 0
>  parts' n [] _ = []                   -- if n /= 0, there are no
> possible partitions of the empty list
>  parts' n remaining atleast = [(x:y) | x <- filter (>= atleast)
> remaining, y <- (parts' (n-x) (remaining \\ [x])) x]
>
>
> *Main> parts 11
> [[1,2,3,5],[1,2,8],[1,3,7],[1,4,6],[1,10],[2,3,6],[2,4,5],[2,9],[3,8],[4,7]
>,[5,6],[11]]

You don't have to have a list of possible parts, the possible parts follow from the
minimum:

parts :: Int -> [[Int]]  -- or (Num a, Ord a) => a -> [[a]]
parts 0 = [[]]
parts n
| n < 0     = []
| otherwise = mpart n 1
where
-- mpart m k partitions m into distinct parts of size at least k
mpart m k
| m < k     = []
| m <= 2*k  = [[m]]
| otherwise = map (k:) (mpart (m-k) (k+1)) ++ mpart m (k+1)

```