12
{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?

AsukaMinato
  • 9,758
  • 1
  • 14
  • 40

4 Answers4

14

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}}
kglr
  • 394,356
  • 18
  • 477
  • 896
2
$$List = {5, 10, 3, 8, 9, 8, 8, 4, 1, 7};

$$Sum = 0; $Max$Value = 20;
 {#, Length@#}& @
     TakeWhile[$$List, (($$Sum += #) <= $Max$Value) &]

(*{{5, 10, 3}, 3}*)
Ernst Stelzer
  • 2,055
  • 12
  • 24
2
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}}

eldo
  • 67,911
  • 5
  • 60
  • 168
2
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}})

E. Chan-López
  • 23,117
  • 3
  • 21
  • 44