7
$\begingroup$

Is there a function that gives all the ways a list can be divided into a specified number of non-overlapping pieces, where the order is maintained?

I can do this with Table. For instance, if the list is:

test={a,b,c,d}

...and I want to see all the ways it can be divided into 2 pieces, this works:

l = Length@test;
Table[{Take[test, i], Take [test, i - l]}, {i, 1, l - 1}];
%//MatrixForm

enter image description here

Just to clarify: If $n=2$, the output I'm looking for would be all the pairs of sublists that, when concatenated, give the original list. E.g., Join[{a},{b,c,d}]===Join[{a,b},{c,d}]===Join[{a,b,c},{d}]==={a,b,c,d}. If $n=3$, it would be all the groups of three sublists that, when concatenated, would give the original list. And so on.

While the Table syntax can be extended to any $n$, I'm wondering if there is a function that gives this more directly—something like (making up a function) Sublists[list, n]. Initially Partition came to mind, but I'm interested in specifying the number of sublists, rather than their lengths.

This seems to be asking a somewhat different question: Partition list into $n$ sublists

$\endgroup$
3
  • $\begingroup$ "all the ways it can be divided into 2 pieces" Why not Tuples[test, 2] ? If you wan to keep subsets with unique entries DeleteDuplicates@Union[#]&/@Tuples[test,2] I do not understand the output you show above, For example where is b,c? $\endgroup$
    – Nasser
    Feb 11 at 5:27
  • 1
    $\begingroup$ @Nasser You wouldn't see {b,c} if test were divided into two pieces such that they are non-overlapping & keep the same order. You would only see that if test were divided into three pieces: {{a}, {b,c}, {d}}. [You could see that if you divided test into two pieces this way: {{a,d},{b,c}}. But that doesn't meet the criterion of maintaining the original order.] Imagine a directional Toblerone bar with 4 "triangles" (so three break points) and you needed to split that bar into exactly two pieces, cutting it only at the break points. I'm asking for all the ways you could do it. $\endgroup$
    – theorist
    Feb 11 at 6:05
  • $\begingroup$ And DeleteDuplicates@Union[#] & /@ Tuples[test, 2] would be for an entirely different problem. Note that, if $n=2$, the output I'm looking for would be all the pairs of sublists that, when concatenated, give the original list. E.g., Join[{a},{b,c,d}] ===Join[{a,b},{c,d}]===Join[{a,b,c},{d}]==={a,b,c,d}. I'll add that clarification to my post. $\endgroup$
    – theorist
    Feb 11 at 6:12

2 Answers 2

5
$\begingroup$

ReplaceList can do this. A variable sized pattern is needed.

Clear[mseq, patt, m, i, test, vars];
Clear[test, a, b, c, d]
vars = ToExpression@Characters@"pqrstuvwxyz"
test = {a, b, c, d}
mseq[m_] := 
 Table[Pattern[Evaluate@vars[[i]], BlankSequence[]], {i, 1, m}]
patt[m_] := Rule[mseq[m], List /@ vars[[1 ;; Length@mseq[m]]]]

Test

patt[3]

{p__, q__, r__} -> {{p}, {q}, {r}}

patt[2]

{p__, q__} -> {{p}, {q}}

Usage

ReplaceList[test, patt[2]]

{{{a}, {b, c, d}}, {{a, b}, {c, d}}, {{a, b, c}, {d}}}

ReplaceList[test, patt[3]]

{{{a}, {b}, {c, d}}, {{a}, {b, c}, {d}}, {{a, b}, {c}, {d}}}
$\endgroup$
5
$\begingroup$
ClearAll[kSubsequencePartitions]
kSubsequencePartitions[lst_, m_] := Sort[TakeList[lst, #] & /@ Join @@ 
   Permutations /@ IntegerPartitions[Length @ lst, {m}, Range[Length @ lst]]];

Examples:

kSubsequencePartitions[{a, b, c, d}, 2] // Column

enter image description here

kSubsequencePartitions[{a, b, c, d}, 3] // Column

enter image description here

kSubsequencePartitions[Range[5], 3] // Column

enter image description here

kSubsequencePartitions[{x, 10, a, 2, b}, 3] // Column

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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