Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Here is a possible recursive (rather lazy) implementation without using specialized iter tools.

def mySplitIntoPieces(S, L):
    """S is a list of "elements", 
    L is a list of positive integers with sum(L) = len(S),
    we want to return the list of all tuples
    [ S0, S1, S2, ... ]
    where S0, S1, S2, ... are a partition of S and 
    len(S0) = L[0],
    len(S1) = L[1],
    len(S2) = L[2],
    and so on.
    """

    if len(S) != sum(L):
        return

    if len(L) == 0:
        return [ S ]    # the partition of S in one piece

    return [ [ S0, ] + furtherPieces
             for S0 in Combinations( S, L[0] )
             for furtherPieces in mySplitIntoPieces( list(set(S).difference(S0)), L[1:] ) ]

Let us test the functionality:

sage: for pieces in mySplitIntoPieces( [0..4], [2,1,2] ): 
....:     print(pieces)                                                                                                                                                                               
[[0, 1], [2], [3, 4]]
[[0, 1], [3], [2, 4]]
[[0, 1], [4], [2, 3]]
[[0, 2], [1], [3, 4]]
[[0, 2], [3], [1, 4]]
[[0, 2], [4], [1, 3]]
[[0, 3], [1], [2, 4]]
[[0, 3], [2], [1, 4]]
[[0, 3], [4], [1, 2]]
[[0, 4], [1], [2, 3]]
[[0, 4], [2], [1, 3]]
[[0, 4], [3], [1, 2]]
[[1, 2], [0], [3, 4]]
[[1, 2], [3], [0, 4]]
[[1, 2], [4], [0, 3]]
[[1, 3], [0], [2, 4]]
[[1, 3], [2], [0, 4]]
[[1, 3], [4], [0, 2]]
[[1, 4], [0], [2, 3]]
[[1, 4], [2], [0, 3]]
[[1, 4], [3], [0, 2]]
[[2, 3], [0], [1, 4]]
[[2, 3], [1], [0, 4]]
[[2, 3], [4], [0, 1]]
[[2, 4], [0], [1, 3]]
[[2, 4], [1], [0, 3]]
[[2, 4], [3], [0, 1]]
[[3, 4], [0], [1, 2]]
[[3, 4], [1], [0, 2]]
[[3, 4], [2], [0, 1]]
sage: