{ { { 1 2 3 4 } } } [ { 1 2 3 4 } [ 4array ] 4 nclump-map ] unit-test
{ { { 1 2 3 4 } { 2 3 4 5 } } } [ { 1 2 3 4 5 } [ 4array ] 4 nclump-map ] unit-test
+{ { } } [ { 1 } [ 3array ] 3 ngroup-map ] unit-test
+{ { } } [ { 1 2 } [ 3array ] 3 ngroup-map ] unit-test
+{ { { 1 2 3 } } } [ { 1 2 3 } [ 3array ] 3 ngroup-map ] unit-test
+{ { { 1 2 3 } } } [ { 1 2 3 4 } [ 3array ] 3 ngroup-map ] unit-test
+
{ { "tail" "ail" "il" "l" } } [ "tail" tail-clump ] unit-test
{ { "h" "he" "hea" "head" } } [ "head" head-clump ] unit-test
: nclump-map ( seq quot n -- result )
{ } swap nclump-map-as ; inline
+:: pad-groups ( seq n elt -- padded )
+ seq dup length dup n mod [ drop ] [ n swap - + elt pad-tail ] if-zero ;
+
+:: short-groups ( seq n -- seq' )
+ seq dup length dup n mod [ drop ] [ - head-slice ] if-zero ;
+
+MACRO:: ngroup-map-as ( seq quot exemplar n -- result )
+ [ seq n short-groups n <groups> [ n firstn quot call ] exemplar map-as ] ;
+
+: ngroup-map ( seq quot n -- result )
+ { } swap ngroup-map-as ; inline
+
TUPLE: head-clumps seq ;
C: <head-clumps> head-clumps
M: head-clumps length seq>> length ;