# Repeating slices of an array incrementally

Let's say I have a non-empty list (array):

l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


I want to incrementally slice the list into incremented amount of elements per chunk.

For this array, my desired output is:

[[1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]


What would be the best way to slice the array in multiple chunks.

This is , so shortest code in bytes wins!

Note: For the final chunk, if the number of elements left in r is less than what the incremented output requires, the last chunk should just be all that remains in the list.

# Test cases:

l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-> [[1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]

l = [10, 20, 30, 40]
-> [[10], [20, 30], [40]]

l = [100, 200, 300, 400, 500]
-> [[100], [200, 300], [400, 500]]

• I suggest adding a test case with repeated elements (or specifying that cannot happen in the input) Dec 27, 2021 at 15:49

# Python, 40 bytes

f=lambda a,n=1:a and[a[:n]]+f(a[n:],n+1)

Attempt This Online!

# Husk, 3 2 bytes

Edit: -1 byte thanks to Razetime

CN


Try it online!

C       # Cut off substrings of the following lengths:
N      # natural numbers

• CN should work Dec 27, 2021 at 14:07
• @Razetime - Oh, yeah, of course. Doh. Will you post that, then? Dec 27, 2021 at 15:00
• nah, it's not worth an extra answer. Add it in if you want to. Dec 27, 2021 at 15:22
• Wow 2 bytes... Is this language just made for this challenge? Dec 28, 2021 at 2:42
• @U12-Forward Husk is (also) a golfing language (see its wiki). Dec 28, 2021 at 2:51

# Vyxal, 2 bytes

żẇ


Try it Online!

## Explained

żẇ­⁡​‎‎⁪⁡⁪⁠⁪⁡⁪‏‏​⁡⁠⁡‌⁢​‎‎⁪⁡⁪⁠⁪⁢⁪‏‏​⁡⁠⁡‌­
ż   # ‎⁡The range [1, len(input)]
ẇ  # ‎⁢Wrap the input list into chunks of each number. Stops grouping when there's no more items
💎


Created with the help of Luminespire.

# Factor + grouping.extras math.unicode, 58 57 bytes

[ dup '[ _ index 1 + 2 * √ .5 + ⌊ ] group-by values ]


Try it online!

Group elements by the integer inverse triangular function of their indices. In other words, given a zero-based index $$\i\$$, its element belongs to group

$$\left\lfloor\sqrt{2(i + 1)} + \frac{1}{2}\right\rfloor$$

# Jelly, 5 bytes

JÄ‘œṖ


Try it online!

### How?

JÄ‘œṖ - Link: list, L                  e.g. [5,4,3,2,1,0,1,2]
J     - range of length of L                [1,2,3,4,5,6,7,8]
Ä    - cumulative sums                     [1,3,6,10,15,21,28,36]
‘   - increment                           [2,4,7,11,16,22,29,37]
œṖ - partition L before those indices    [[5],[4,3],[2,1,0],[1,2]]


Also 5 bytes TIO:

Jx¹ƙ


...(J) range of length, () use right as both arguments with (x) repeat elements then (ƙ) apply to groups of identical values (¹) a no-op function.
i.e. build a list like [1,2,2,3,3,3,4,4,4,4,...] and group the original values like its equal values, [[1],[2,2],[3,3,3],[4,4,4,4],...].

or, equivalently (just reapplying J rather than using the quick ):

JxJ¹ƙ

• Wow!! 5 bytes, but just curious, there is ÇŒṘ in the footer, what does that do? Dec 28, 2021 at 2:18
• @U12-Forward The entry is a monadic function (AKA Link), but I want to avoid Jelly's full-program output formatting. Ç calls the Link above and ŒṘ formats the list in a Python style (Jelly's full-program output formatting shows singleton lists as the element they contain, so the example I give would look like [5,[4,3],[2,1,0],[1,2]] instead. (Jelly's list representation also smashes characters or mixed type lists, so [5,6,'a'] would be output as 56a which doesn't matter here, but both can be useful since we usually have the option of writing a function or full program.) Dec 28, 2021 at 2:35
• Wow! Nice answer, 5 bytes... How?
– user110034
Dec 28, 2021 at 2:41
• @richardec Jelly is a language for golfing. See "How?" and if interested see the wiki. Dec 28, 2021 at 2:43
• @JonathanAllan Thanks for the explanation. Interested in Jelly, for golfing. Might want to learn some of it. Dec 28, 2021 at 2:48

# Ruby, 38 bytes

->l{(1..l.size).map{l.shift(_1)}-[[]]}

• Welcome to Code Golf, and nice answer! Dec 27, 2021 at 20:20
• Thanks @RedwolfPrograms Dec 28, 2021 at 7:26

# Charcoal, 21 bytes

≔⮌ＡθＷθ⊞υＥ⌊⟦Ｌθ⊕Ｌυ⟧⊟θＩυ


Try it online! Link is to verbose version of code. Explanation:

≔⮌Ａθ


Reverse the input list.

Ｗθ


Repeat until it is empty...

⊞υＥ⌊⟦Ｌθ⊕Ｌυ⟧⊟θ


... pop up to the next number of items from the input list into a new group.

Ｉυ


Output the grouped list.

# R, 40 bytes

function(x)split(x,rep(s<-seq(!x),s)[s])


Try it online!

Inspired by Giuseppe's answer to "Chunk sort a sequence".

• I thought this challenge felt familiar! Nicely done. Dec 27, 2021 at 16:48

# J, 12 bytes

</.~#{.#\##\


Try it online!

Consider 10 20 30 40 50 60:

• #\ Gives 1 2 3 4 5 6 (ie, 1...n).

• #\##\ Uses that list to "copy" itself:

1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 6 6 6 6 6 6

• #{. Take only the first n elements of that:

1 2 2 3 3 3

• </.~ Group the original input using that mask:

┌──┬─────┬────────┐
│10│20 30│40 50 60│
└──┴─────┴────────┘

• Nice approach! A Jelly port ties the existing 5-byte answer: JxJ¹ƙ.
– Lynn
Dec 27, 2021 at 20:20

n![]=[]
n!x=take n x:(n+1)!drop n x
(1!)


Try it online!

There seems like there should be a shorter way to do this maybe with scans or folds, but I can't figure it out.

• I think this needs a newline and (1!) included in the byte count.
– Lynn
Dec 27, 2021 at 20:16

# APL+WIN, 18 bytes

Prompts for a vector of numbers or a string of characters. Outputs a nested vector.

(m↑(⍳m)/⍳m←⍴n)⊂n←⎕


Try it online! Thanks to Dyalog Classic

# Perl 5, 45 bytes

sub{my@r;push@r,[splice@_,0,1+@r]while@_;\@r}


Try it online!

# Scala, 92 bytes

a=>if(a.last.size>a.size)f(a.init++Seq(a.last.take(a.size))++Seq(a.last.drop(a.size)))else a


Try it online!

# C (gcc), 86 $$\\cdots\$$ 77 76 bytes

r;i;f(a,n)int*a;{for(i=r=1;n--;r+=r*~r/2+i++?0:puts(""))printf("%d ",*a++);}


Try it online!

Saved a byte thanks to ceilingcat!!!

Inputs a pointer to an array of integers and its length (because pointers in C carry no length info).
Outputs to stdout each array slice with the array elements separated by spaces and the slices separated by newlines.

# BQN, 24221514 12 bytes

Edit: -2 bytes thanks to Razetime, and -2 more bytes (and a BQN lesson) thanks to ovs

 1↓⊢⊔˜≠⥊·/˜⊒˜


Try it at BQN online REPL

• ∾⥊¨˜ becomes /˜ Dec 27, 2021 at 17:19
• @Razetime - (1) Thanks for spotting; (2) Drat! I'm sure I had it working in the REPL, but now I've lost how I did it (if at all...). Replaced with a longer working version for now, while I try to fix the shorter one... (3) And thanks v much for offer to help: I'll struggle a bit, and maybe ping you if I can't manage... Dec 27, 2021 at 17:20
• @Razetime - Fixed. I'd somehow lost a ˜... Dec 27, 2021 at 18:51
• 1↓⊢⊔˜≠⥊·/˜⊒˜ saves 2 bytes; The link includes a few steps, but it is a combinations of this tip and using Nothing to call a function monadically in a train.
– ovs
Dec 27, 2021 at 22:19
• The functions you put in parens are all applied to the argument(s) of the entire train. ⊢ is not really the right argument of the train but rather a function that returns its right argument. (≠⊢) is a 2-train which calls ≠ on the result of ⊢ (Equivalent to ≠∘⊢ - length atop right). Because the entire train is only applied to an argument on the right, this has the same effect as a bare ≠ (If the train would be called with a left argument, (≠⊢) and (≠) wouldn't be equivalent).
– ovs
Dec 28, 2021 at 22:44

# Wolfram Language (Mathematica), 33 bytes

GatherBy[#,i=1;Round@√(2i++)&]&


Try it online!

# Uiua, 11 bytes

⊜□⬚2↙⧻,⊚⇡⧻.


Try it!

⊜□⬚2↙⧻,⊚⇡⧻.
.  # duplicate
⧻   # length
⇡    # range
⊚     # where
,      # over
⧻       # length
⬚2↙        # take with fill element of 2
⊜□           # partition with boxing

• If you want to handle arrays with repeated elements, I think you'll need to swap 'classify' for 'range-length', or something like that... Oct 16, 2023 at 7:40
• @DominicvanEssen Thanks. Fixed for +1. Oct 16, 2023 at 17:29

# Python 2, 47 bytes:

def f(l,c=1):
while l:yield l[:c];l=l[c:];c+=1


Try it Online!

# JavaScript (ES6), 42 bytes

-2 thanks to @emanresuA because I'm a potato

x=>(f=n=>x+x&&[x.splice(0,++n),...f(n)])$$$$


# Python 3, 71 bytes

g=lambda x,s=1:[[c for c,_ in zip(x,range(s))]]+g(x[s:],s+1)if x else[]


Try it online!

-3 Thanks to @U12-Forward

• Dec 27, 2021 at 12:30

# Pip-xp, 12 bytes

a^@$+*\,\,#a  Attempt This Online! ### Explanation a^@$+*\,\,#a
#a  Length(argument)
\,    Inclusive range from 1 to ^
\,      Inclusive range from 1 to each number in ^
\$+*        Sum each
a^@           Split argument at those indices


## Scala, 74 bytes

a=>(0 to a.size).map(i=>a.slice(i*(i+1)/2,(i+1)*(i+2)/2)).filter(_.size>0)


Try it online!

The obvious way to avoid the filter at the end is to make the range from 0 to the biggest triangle number whose value is less than a.size, but the shortest way I could find to express that in Scala 2.13 was longer than the thing it was supposed to replace:

BigDecimal(0).until(pow(2*a.size+.25,.5)-.5,1)


# Raku, 22 bytes

*.rotor(1..*,:partial)


Try it online!

The rotor method splits an array into chunks of a given size or sizes, eg:

• rotor(5) splits an array into 5-element chunks.
• rotor(2, 3) splits an array into chunks of alternating sizes 2 and 3.

Here, I pass the infinite range 1 .. * as the argument, so rotor will emit chunks of sizes 1, 2, 3, .... The :partial keyword argument causes all remaining elements to be grouped into the final chunk, even if there aren't enough of them.

# APL (Dyalog Unicode), 17 bytes

This is a dfn that takes a vector as a right argument. It groups segments per specification into a nested array of vectors.


{⍵⊆⍨1+q⍸⍨+\q←⍳⍴⍵}

`

The index origin is set to 0 (⎕IO←0).

Try it on TryAPL.org!

This was an interesting challenge and demonstrates that there are many ways to get to a solution in the APL language. None I found had a lesser byte count, but the approaches may be of interest:

by recursion: {⍺←1 ⋄ ⍺≥⍴⍵:⊂⍵ ⋄ (⊂⍺↑⍵),(⍺+1)∇ ⍺↓⍵}

by formula: {⍵⊆⍨⌊0.5+0.5*⍨2×⍳⍴⍵}

by iteration: {p⊆⍨q↑∊{⍵⍴⍵}¨⍳q←⍴⍵}