NOTE
I'm sorry, my question was not clear. I want to know all the ways to split a list with a given length simply, rather than split a cyclic substitution. If a given list has length $N$ and the rule is ${m, n, p, ...}$, we should get a list of length ${}_{N} C_{m} {}_{N-m} C_{n} {}_{N-m-n} C_{p} \dots = \frac{N!}{m! n! p! \cdots}$ if all elements of $N$ are independent.
Other examples:
Length@partitionList[{a, b, c, d, e, f, g, h}, {2, 2, 4}]
returns $420 = \frac{8!}{2! 2! 4!}$
Length@partitionList[{a, b, b, c, d, e, e, f}, {2, 2, 4}]
returns 173
Question
I want to split a given list into sets of lists, whose lengths are given.
For example, this means if we split a list {a, b, c, d}
(length 4) to two lists with length {1, 3}
(the sum of lengths should be 4), we obtain
{{{a}, {b, c, d}}, {{b}, {c, d, a}}, {{c}, {d, e, a}}, {{d}, {e, a, b}}
(here, we don't care about ordering for elements in each sublist).
To achieve this, I prepared the following function:
partitionList[l_List, p_List] :=
DeleteDuplicates@(Module[{$tmp, $deleteList, $lastchoose,
l2 = Range[Length@l]},
$tmp = Subsets[l2, {p[[1]]}];
$deleteList = Flatten /@ $tmp;
If[Length@p > 1,
Do[
$lastchoose =
Table[Subsets[
Delete[l2, {#} & /@ $deleteList[[$j]]], {p[[$i]]}], {$j,
Length@$deleteList}];
$tmp =
Replace[Flatten[
Tuples /@ Transpose[{{#} & /@ $tmp, $lastchoose}], 1],
x_ /; Depth@x > 2 :> Sequence @@ x, {2} ];
$deleteList = Flatten /@ $tmp;
, {$i, 2, Length@p}]
];
Map[l[[#]] &, $tmp, {2}]
]
)
Here, the argument $l$ is a list which we want to split, and $p$ is a list of lengths of sublists.
In the previous example, $l$ is {a, b, c, d}
and $p$ is {1, 3}
.
However, since it is based on procedural programming, I believe there are more efficient ways. Could you please suggest such a method?
Select[Subsets[ Subsets[{a, b, c, d}]], (! MemberQ[#, {}] && Length[Flatten@#] == 4) &]
$\endgroup$