This is a complete re-write
This is the original solution which was done in haste but i will leave here. It works in limited cases:
multisegment[lst_List, scts_List, offset_List] :=
Module[{acc, offs},
offs = 1+Prepend[Accumulate[PadRight[offset,
1 + Ceiling[Length[lst]/Total[offset]], offset]], 0];
acc = PadRight[scts, Length[offs],scts];
acc = acc + offs - 1;
Inner[Take[lst, {#1, #2}] &, offs, acc, List]
]
multisegment[Range[14], {4, 3}, {3, 1}]
{{1, 2, 3, 4}, {4, 5, 6}, {5, 6, 7, 8}, {8, 9, 10}, {9, 10, 11,
12}, {12, 13, 14}}
To solve this you note that the starting position (for Part
or Take
) of the list depends solely on the offset list:
{1,4,5,8,9,12}
The "span to" position is determined by adding the partition list
{4,3,4,3,4,3}
to the offset list (minus 1) to give
{4,6,8,10,12,14}
From there, proceed as before with Inner
and use either Take
or Part
. So this becomes an exercise in generating the correct offset list. As earlier failed attempts have shown, this is dependent on both the total of the offsets and the length of the offsets (list).
But also you do not want your Take
or "span to" range exceeding the length of your target list. I have taken the easy way out here but using DeleteCases
. A more exact and possibly elegant, but maybe not faster (?), approach is to actually work this out based on the partition list.
multisegment[lst_List, scts_List, offset_List] :=
Module[{fin, offs, len = Length[lst], tot = Total[offset], len2 = Length[offset]},
offs = 1 + Prepend[Accumulate[
PadRight[offset, Ceiling[len2*len/tot], offset]], 0];
fin = PadRight[scts, Length[offs], scts] + offs - 1;
fin = DeleteCases[Transpose[{offs, fin}], {_, x_ /; x > len}];
Take[lst, #] & /@ fin]
(* case for no offsets *)
multisegment[lst_List, scts_List] := multisegment[lst, scts, scts]
I prefer to layout the code in steps rather than combine multiple steps into a one (or two) liner. Feel free to do that if you wish but I think this way makes it easier for people to check out what is happening.
Also a qualifier: checks and/or conditions should be added. you cannot have {0} for your partition or offset. Must be integers etc. as per Simon's comments.
Usage. First the base case of an uneven partition with no offset
multisegment[Range[14], {3, 4}]
{{1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10}, {11, 12, 13, 14}}
now add an offset
multisegment[Range[14], {3, 4}, {1, 2}]
{{1, 2, 3}, {2, 3, 4, 5}, {4, 5, 6}, {5, 6, 7, 8}, {7, 8, 9}, {8, 9,
10, 11}, {10, 11, 12}, {11, 12, 13, 14}}
Examples that previously failed:
multisegment[Range[10], {5, 4}, {2, 3}]
{{1, 2, 3, 4, 5}, {3, 4, 5, 6}, {6, 7, 8, 9, 10}}
multisegment[Range[100], {5, 4}, {2, 3}]
{{1, 2, 3, 4, 5}, {3, 4, 5, 6}, {6, 7, 8, 9, 10}, {8, 9, 10, 11}, {11,
12, 13, 14, 15}, {13, 14, 15, 16}, {16, 17, 18, 19, 20}, {18, 19,
20, 21}, {21, 22, 23, 24, 25}, {23, 24, 25, 26}, {26, 27, 28, 29,
30}, {28, 29, 30, 31}, {31, 32, 33, 34, 35}, {33, 34, 35, 36}, {36,
37, 38, 39, 40}, {38, 39, 40, 41}, {41, 42, 43, 44, 45}, {43, 44,
45, 46}, {46, 47, 48, 49, 50}, {48, 49, 50, 51}, {51, 52, 53, 54,
55}, {53, 54, 55, 56}, {56, 57, 58, 59, 60}, {58, 59, 60, 61}, {61,
62, 63, 64, 65}, {63, 64, 65, 66}, {66, 67, 68, 69, 70}, {68, 69,
70, 71}, {71, 72, 73, 74, 75}, {73, 74, 75, 76}, {76, 77, 78, 79,
80}, {78, 79, 80, 81}, {81, 82, 83, 84, 85}, {83, 84, 85, 86}, {86,
87, 88, 89, 90}, {88, 89, 90, 91}, {91, 92, 93, 94, 95}, {93, 94,
95, 96}, {96, 97, 98, 99, 100}}
Example showing it working with increasing offset list length
multisegment[Range[44], {3, 4}, {1, 3, 2}]
{{1, 2, 3}, {2, 3, 4, 5}, {5, 6, 7}, {7, 8, 9, 10}, {8, 9, 10}, {11,
12, 13, 14}, {13, 14, 15}, {14, 15, 16, 17}, {17, 18, 19}, {19, 20,
21, 22}, {20, 21, 22}, {23, 24, 25, 26}, {25, 26, 27}, {26, 27, 28,
29}, {29, 30, 31}, {31, 32, 33, 34}, {32, 33, 34}, {35, 36, 37,
38}, {37, 38, 39}, {38, 39, 40, 41}, {41, 42, 43}}
multisegment[Range[44], {3, 4}, {1, 3, 2, 4}]
{{1, 2, 3}, {2, 3, 4, 5}, {5, 6, 7}, {7, 8, 9, 10}, {11, 12, 13}, {12,
13, 14, 15}, {15, 16, 17}, {17, 18, 19, 20}, {21, 22, 23}, {22, 23,
24, 25}, {25, 26, 27}, {27, 28, 29, 30}, {31, 32, 33}, {32, 33, 34,
35}, {35, 36, 37}, {37, 38, 39, 40}, {41, 42, 43}}
and so on, and so forth.
Block
rather thanModule
? $\endgroup$ – Mike Honeychurch Jan 30 '12 at 3:37Module[]
in there... $\endgroup$ – J. M.'s ennui♦ Jan 30 '12 at 3:40scts
mean? Namely, which word'sabbreviation
isscts
? $\endgroup$ – xyz Sep 24 '14 at 6:26