# How to cut a list by max sum

{5, 10, 3, 8, 9, 8, 8, 4, 1, 7}


let maxsum=20, then I get {{5, 10, 3}, {8, 9}, {8, 8, 4}, {1, 7}} , all the sum of sublist $$\le$$ maxsum. (Assume there won't be any element $$>$$ maxsum)

This is what I have coded.

F[x_] := Module[{a = {}, s = {}}, Do[AppendTo[s, i]; If[Total[s] > 20, AppendTo[a, s // Most];
s = {i}], {i, x}]; AppendTo[a, s]; a]

F[{1, 2, 3, 4, 6, 4, 3}]

(*{{1, 2, 3, 4, 6, 4}, {3}}*)


Any other way to achieve this?

• Similar to 268488 that was asked in 2022.
– Syed
May 6, 2023 at 3:46

### Split

ClearAll[split]
split[lst_, maxsum_] := Module[{s = lst[[1]]},
Split[lst, Or[(s+= #2) <= maxsum, s = #2] &]]


Examples:

split[{5, 10, 3, 8, 9, 8, 8, 4, 1, 7}, 20]

 {{5, 10, 3}, {8, 9}, {8, 8, 4}, {1, 7}}

split[{1, 2, 3, 4, 6, 4, 3}, 20]

 {{1, 2, 3, 4, 6, 4}, {3}}


### SequenceSplit

ClearAll[seqSplit]
seqSplit = SequenceSplit[#, a : {__} /; Total[a] <= #2 :> a] &;

seqSplit[{5, 10, 3, 8, 9, 8, 8, 4, 1, 7}, 20]

{{5, 10, 3}, {8, 9}, {8, 8, 4}, {1, 7}}

seqSplit[{1, 2, 3, 4, 6, 4, 3}, 20]

 {{1, 2, 3, 4, 6, 4}, {3}}


### Reap + Sow

ClearAll[reapSow]
reapSow[lst_, maxsum_] := Module[{i = 0, s = 0},
Last @ Reap[Scan[Sow[#, If[(s += #) <= maxsum, i, s = #; ++i]] &, lst]]]

reapSow[{5, 10, 3, 8, 9, 8, 8, 4, 1, 7}, 20]

{{5, 10, 3}, {8, 9}, {8, 8, 4}, {1, 7}}

reapSow[{1, 2, 3, 4, 6, 4, 3}, 20]

 {{1, 2, 3, 4, 6, 4}, {3}}


### ReplaceRepeated + TakeDrop + Accumulate

takeDrop[lst_, maxsum_] := {lst} //. {a___List, b_List} /; Length[b] > 1 :>
{a, ## & @@ TakeDrop[b, LengthWhile[Accumulate[b], # <= maxsum &]]} //
DeleteCases[{}]

takeDrop[{5, 10, 3, 8, 9, 8, 8, 4, 1, 7}, 20]

 {{5, 10, 3}, {8, 9}, {8, 8, 4}, {1, 7}}

takeDrop[{1, 2, 3, 4, 6, 4, 3}, 20]

 {{1, 2, 3, 4, 6, 4}, {3}}

$$List = {5, 10, 3, 8, 9, 8, 8, 4, 1, 7}; $$Sum = 0; MaxValue = 20; {#, Length@#}& @ TakeWhile[$$List, (($$Sum += #) <= $Max$Value) &]

(*{{5, 10, 3}, 3}*)

list = {5, 10, 3, 8, 9, 8, 8, 4, 1, 7};


Using SequenceCases

SequenceCases[list, a_ /; Total[a] <= 20]


{{5, 10, 3}, {8, 9}, {8, 8, 4}, {1, 7}}

list = {5, 10, 3, 8, 9, 8, 8, 4, 1, 7};


Using SequenceReplace:

SequenceReplace[list, {a__} /; Total[{a}] <= 20 :> {a}]

(*{{5, 10, 3}, {8, 9}, {8, 8, 4}, {1, 7}}*)