23
\$\begingroup\$

05AB1E has the £ builtin which, given a list of integers b and a string s, splits s into sublists of lengths equal to the elements in b. For example, [1,2,3,4,1] "hello world"£ produces ["h", "el", "lo ", "worl", "d"]. Your task is to imitate this behaviour.

Given a list \$L\$ containing \$n\$ elements, and a list \$B\$ of positive integers that sum to \$n\$, emulate the behaviour of £ in 05AB1E. \$L\$ will always contain positive digits (so 123456789), \$n\$ will always be greater than or equal to \$1\$ and will never exceed your language's maximum integer.

If you have a builtin which mimics this exact behaviour, such as 05AB1E's £, you may not use it. Every other builtin, including ones that partition the input into slices of a given integer length are acceptable. Essentially, any command that is not a standalone answer to this challenge is acceptable.

You may take the two lists in any convenient method or format, including taking \$L\$ as an integer. You may optionally take \$n\$ as input. You may output in any format that clearly shows the sublists of \$L\$, distinct from each other. For example, outputting integers separated by newlines, or outputting a list of lists of digits.

This is , so the shortest code in bytes wins.

Test cases

L, B -> output
[[4, 5, 1, 2, 6, 1, 7, 9, 6], [2, 4, 3]] -> [[4, 5], [1, 2, 6, 1], [7, 9, 6]]
[[4, 2, 8, 7, 3, 5, 9, 3, 1, 9, 1, 8, 1, 7, 2, 8, 3, 7, 6], [1, 3, 1, 14]] -> [[4], [2, 8, 7], [3], [5, 9, 3, 1, 9, 1, 8, 1, 7, 2, 8, 3, 7, 6]]
[[8, 7, 4, 6], [1, 3]] -> [[8], [7, 4, 6]]
[[7], [1]] -> [[7]]
[[6, 4, 3, 8, 9, 3, 6, 5, 7, 8, 3, 2, 5, 1, 2], [3, 3, 3, 3, 3]] -> [[6, 4, 3], [8, 9, 3], [6, 5, 7], [8, 3, 2], [5, 1, 2]]
[[2, 7, 9, 3, 8, 1, 5], [4, 3]] -> [[2, 7, 9, 3], [8, 1, 5]]
[[1, 9, 8, 9, 6, 3, 4, 2, 3, 4, 1, 8, 5, 5, 2, 9, 3, 6, 7], [3, 1, 2, 13]] -> [[1, 9, 8], [9], [6, 3], [4, 2, 3, 4, 1, 8, 5, 5, 2, 9, 3, 6, 7]]
[[1, 8, 7, 8, 9, 4, 2, 5, 2, 7, 1, 5, 2, 3, 8, 4, 6, 9, 1, 9, 3, 4, 6, 7, 6, 5, 3], [7, 7, 3, 8, 2]] -> [[1, 8, 7, 8, 9, 4, 2], [5, 2, 7, 1, 5, 2, 3], [8, 4, 6], [9, 1, 9, 3, 4, 6, 7, 6], [5, 3]]
[[7, 4, 4, 7, 5, 5], [1, 2, 3]] -> [[7], [4, 4], [7, 5, 5]]
[[9, 2, 8, 7, 2, 3, 9, 5, 8, 1, 5, 2], [2, 2, 2, 2, 2, 1, 1]] -> [[9, 2], [8, 7], [2, 3], [9, 5], [8, 1], [5], [2]]
[[8, 7, 3], [3]] -> [[8, 7, 3]]
[[8, 2, 7, 3, 9, 5, 6, 9, 5, 3, 1, 9, 7, 5, 3, 6, 4, 1], [2, 1, 2, 6, 2, 2, 3]] -> [[8, 2], [7], [3, 9], [5, 6, 9, 5, 3, 1], [9, 7], [5, 3], [6, 4, 1]]
[[8, 2, 3, 7, 4, 7, 7, 4, 5, 5, 8, 1, 2, 3, 3], [3, 7, 4, 1]] -> [[8, 2, 3], [7, 4, 7, 7, 4, 5, 5], [8, 1, 2, 3], [3]]
[[4, 3, 8, 9, 9, 3, 2, 5, 5, 8, 2, 8, 1, 1, 4, 1], [10, 5, 1]] -> [[4, 3, 8, 9, 9, 3, 2, 5, 5, 8], [2, 8, 1, 1, 4], [1]]
[[6, 3, 2, 9, 5, 6, 1, 4, 9, 4, 2, 5, 6, 8, 8, 5], [4, 3, 2, 1, 2, 2, 2]] -> [[6, 3, 2, 9], [5, 6, 1], [4, 9], [4], [2, 5], [6, 8], [8, 5]]
[[2, 2, 1, 6, 8, 5, 2, 6, 7, 9, 4, 5, 8, 1, 9, 6, 3, 8, 7, 3, 9, 1], [6, 7, 1, 2, 2, 2, 2]] -> [[2, 2, 1, 6, 8, 5], [2, 6, 7, 9, 4, 5, 8], [1], [9, 6], [3, 8], [7, 3], [9, 1]]
\$\endgroup\$
1
  • \$\begingroup\$ I have 4 bytes here in Jelly, brownie points for beating/matching it \$\endgroup\$ Aug 7 at 1:21

26 Answers 26

10
\$\begingroup\$

Jelly, 3 bytes

Rṁ@

Try It Online!

Equivalently, ṁR} but with the arguments the other way around.

R    Range (vectorizes)
 ṁ@  Mold the right argument to the shape of the ranges
ṁ    Mold the left argument to the shape of:
 R}  Range (vectorizes) of the right argument
\$\endgroup\$
9
\$\begingroup\$

Python 2, 39 bytes

lambda L,B:[map(L.pop,[0]*x)for x in B]

Try it online!

\$\endgroup\$
7
\$\begingroup\$

05AB1E, 5 bytes

I've tried to implement £ manually way too often because the docs just say £ - Head. Push a[0:b], which is exactly what this builtin does if you just pass a single integer.

L˜Å¡¦

Try it online!

L convert each length n into a range [1 .. n]
˜ flatten into a list of integers
Å¡ split the sequence on 1's (the only truthy value in 05AB1E)
¦ remove the leading empty list that was created by splitting at index 0

\$\endgroup\$
6
\$\begingroup\$

Haskell, 34 bytes

(zipWith take<*>).scanl(flip drop)

Try it online!

scanl(flip drop) takes the input and sucessively drops off prefixes.

Prelude> scanl(flip drop) "Test string, test string, 123" [6,1,2,3]
[ "Test string, test string, 123"
, "tring, test string, 123"
, "ring, test string, 123"
, "ng, test string, 123"
, " test string, 123"
]

Note that the first result will always be the input string.

Once we have that we apply zipWith take to then take off the prefixes for each size.

\$\endgroup\$
2
  • \$\begingroup\$ Slightly off topic: What do you use for experimenting with Haskell? IDE, VS Code, special vim setup? \$\endgroup\$
    – Jonah
    Aug 7 at 17:04
  • 1
    \$\begingroup\$ @Jonah For experimenting I use ghci. It is very good for interactive stuff. Other than that I pretty much just write code-golf directly TIO. And of course I use pointfree.io it's an excellent tool. \$\endgroup\$
    – Wheat Witch
    Aug 7 at 19:11
6
\$\begingroup\$

APL (Dyalog Extended), 3 bytes

-2 thanks to ovs!

⍸⍛⊆

How does it work?

Firstly ⍸2 4 3 is 1 1 2 2 2 2 3 3 3.

We can then use this to partition () the right argument into chunks.

Try it online!

\$\endgroup\$
5
  • \$\begingroup\$ Why is ⍸4 2 3 equal to 1 1 2 2 2 2 3 3 3? \$\endgroup\$ Aug 7 at 1:51
  • \$\begingroup\$ ⍸ is like 'where', so ⍸0 1 0 0 1 0 1 is 2 5 7, but it's extended to work on any integers not just booleans (oops I put 4 2 3 not 2 4 3) \$\endgroup\$
    – rak1507
    Aug 7 at 1:58
  • \$\begingroup\$ ⍸⍛⊆ for 3 bytes \$\endgroup\$
    – ovs
    Aug 7 at 8:50
  • \$\begingroup\$ @ovs oh wow that's so obvious now I think about it, thanks! \$\endgroup\$
    – rak1507
    Aug 7 at 13:22
  • \$\begingroup\$ /⊸⊔ in BQN, character by character \$\endgroup\$
    – Razetime
    Aug 7 at 15:40
6
\$\begingroup\$

R >= 4.1, 30 29 bytes

\(L,B)split(L,rep(seq(!B),B))

Try it online!

An anonymous function taking two vectors and returning a list of vectors.

Thanks to @pajonk for saving a byte!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Exactly what I had in mind :-) Also, -1 byte? \$\endgroup\$
    – pajonk
    Aug 7 at 11:57
5
\$\begingroup\$

J, 6 bytes

</.~I.

Try it online!

Called with the list as left arg, grouping mask as right arg.

The whole thing is a dyadic hook, so that...

  • I. applies only to the grouping mask, and expands it in place using unique elements. Eg, I. 2 4 3 becomes:

    0 0 1 1 1 1 2 2 2
    
  • </.~ That mask is used to group /. the list itself, putting each group into a box <.

\$\endgroup\$
5
\$\begingroup\$

Python 2, 42 bytes

Inputs \$ L \$ and \$ B \$ as two comma separated lists from STDIN, and outputs sublists each on one line.

L,B=input()
for x in B:print L[:x];L=L[x:]

Try it online!

\$\endgroup\$
5
\$\begingroup\$

JavaScript (ES6), 44 bytes

Expects (a)(b).

a=>g=([v,...b])=>v?[a.splice(0,v),...g(b)]:b

Try it online!

(or 43 bytes with linefeeds)

\$\endgroup\$
5
\$\begingroup\$

Haskell, 35 34 bytes

x?(c:d)=take c x:drop c x?d
x?_=[]

Try it online!

-1, thanks Wheat Wizard!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can save 1 byte by moving the first case down a line and writing it as x?_=[]. \$\endgroup\$
    – Wheat Witch
    Aug 7 at 13:06
  • \$\begingroup\$ @WheatWizard Aha, thanks! I didn't realise that would cover the (c:[]) case too. \$\endgroup\$ Aug 7 at 13:08
4
\$\begingroup\$

Factor, 24 bytes

[ [ cut swap ] map nip ]

Try it online!

Mapping the lengths to the part of the input that gets 'cut off.' Cutting a sequence into two parts and getting at the results is efficient in bytes because both pieces just end up on the data stack, instead of locked away inside some collection. Process looks something like this:

  1. "hello world" { 1 2 3 4 1 }
  2. "ello world" { "h" 2 3 4 1 }
  3. "lo world" { "h" "el" 3 4 1 }
  4. "world" { "h" "el" "lo " 4 1 }
  5. "d" { "h" "el" "lo " "worl" 1 }
  6. "" { "h" "el" "lo " "worl" "d" }
  7. { "h" "el" "lo " "worl" "d" }
\$\endgroup\$
4
\$\begingroup\$

WolframLanguage (Mathematica), 28 25 bytes

TakeDrop~FoldPairList~##&

–3 bytes from att.

Try it online!

With the prohibitied built-in (introduced in 2017 with v. 11.2), it's 8 bytes:

TakeList
\$\endgroup\$
1
  • 1
    \$\begingroup\$ 25 bytes. (TakeList without the explicit arguments would work if it wasn't prohibited) \$\endgroup\$
    – att
    Aug 7 at 2:44
4
\$\begingroup\$

Brachylog, 7 bytes

~cʰ\l₎ᵐ

Try it online!

~cʰ split the left argument into groups, \ transpose so we have a list of (group, length), l₎ᵐ map each pair: the right element is the length of the left element (which is also the output of l).

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Shame ⟨~clᵐ⟩ just doesn't parse. Nice job remembering \ exists, though--I know I didn't \$\endgroup\$ Aug 9 at 3:00
4
\$\begingroup\$

Japt -m, 3 bytes

Takes B as the first input.

VvU

Try it

VvU     :Implicit map of each U in first input (B)
V       :Second input (L)
 vU     :Remove and return the first U elements
\$\endgroup\$
4
\$\begingroup\$

Desmos, 128 117 bytes

a=length(B)
g(l)=\sum_{k=1}^{[1...length(l)]}l[k]
f=\prod_{n=1}^a\{g(B)[n]+n=[1...\length(L)+a]:0,1\}
h(L,B)=L[g(f)]f

Implements a function \$h(L,B)\$. Output is a list of numbers, with each sublist separated by a zero.

Try It On Desmos!

Try It On Desmos! - Verbose

Explanation:

a=length(B): A helper value that stores the length of the list B specified in the challenge description.

g(l)=\sum_{k=1}^{[1...length(l)]}l[k]: A helper function that returns the running total(as a list) of the list argument l.

f=\prod_{n=1}^a\{g(B)[n]+n=[1...\length(L)+a]:0,1\}: Creates a list of 0's and 1's, which will be used later to determine the format of the final outputted list(0's mean sublist separator, 1's mean to put an element of L there, where L is specified in the challenge description.).

h(L,B)=L[g(f)]f: The actual function that outputs the answer, with each sublist separated by a zero.

\$\endgroup\$
4
\$\begingroup\$

K (ngn/k), 8 bytes

{.=x!&y}

Try it online!

Takes the list of values as x and the lengths of the chunks as y.

  • &y convert length of chunks from e.g. 2 4 3 to 0 0 1 1 1 1 2 2 2
  • x! make a dictionary mapping the original input to these indices
  • = "group" that dictionary (i.e., map the distinct values of the dictionary to their corresponding keys)
  • . return just the values (i.e., the original values, split into chunks of the correct lengths)
\$\endgroup\$
1
  • 2
    \$\begingroup\$ same bytecount: {.x@=&y}.. this solution also works without the dot in Kona since "group" does not create a dictionary there. \$\endgroup\$
    – Traws
    Aug 12 at 1:40
3
\$\begingroup\$

Vyxal r, 5 bytes

vɾ:?•

Try it Online!

If generators weren't so broken, it'd just be vɾ• and flagless.

Explained

vɾ:?•
vɾ    # vectorise range for each item in the shape list
 :   # and duplicate it to dereference it. This is because of the way generators are implemented internally and will be fixed in v2.6
  ?  # get the list to reshape
   • # and mold that to the shape list

So essentially, a port of hyper's jelly

\$\endgroup\$
2
3
\$\begingroup\$

Stax, 3 bytes

m%s

Run and debug it

Takes a string of digits, and the partitions as an integer array.

outputs each slice with a newline.

\$\endgroup\$
3
\$\begingroup\$

Charcoal, 10 bytes

≔⮌θθEη⭆ι⊟θ

Try it online! Link is to verbose version of code. Outputs a newline-separated list of digit strings. Explanation:

≔⮌θθ

Reverse L.

Eη⭆ι⊟θ

For each element of B, pop that many elements from L, and concatenate the digits into a string for output.

\$\endgroup\$
2
\$\begingroup\$

Python 3, 76 bytes

def f(x,n):x=iter(x);return[[*islice(x,a)]for a in n]
from itertools import*

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Ruby, 44 26 bytes

->b,l{b.map{|x|l.shift x}}

Try it online!

-18 thanks to dingledooper

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I think simply ->b,l{b.map{|x|l.shift x}} would suffice. \$\endgroup\$ Aug 7 at 7:15
  • \$\begingroup\$ Ha, that's a lot better. Should have seen it. Thanks. \$\endgroup\$
    – Jonah
    Aug 7 at 7:33
2
\$\begingroup\$

C (gcc), 65 58 bytes

f(s,b,l)int*s,*b;{for(;l--;s+=*b++)printf("%.*ls ",*b,s);}

Try it online!

Inputs a pointer to a list of digits as a wide-character string, a pointer to a list of integer lengths and that list's length (since pointers in C carry no length info).
Outputs the sub-lists separated by spaces.

\$\endgroup\$
2
\$\begingroup\$

Scala, 64 bytes

s=>_./:(Seq[Any]()->s){case(a->s,x)=>(a:+s.take(x),s drop x)}._1

Try it online!

Called as f(fullList)(sublistSizes)

s =>   //The sequence of integers to be split
 _     //The sizes for it to be split into
  ./:  //Fold over it,
   (Seq[Any]()->s) //Starting with an empty list of sublists, and the original list
   {case(a->s,x) => //a is the current list of sublists, s is the current full list, x is the current element
    (a:+s.take(x),  //Add the first x elements of s as a sublist
     s drop x)      //Drop x elements from the full list
   }._1             //Only keep the list of sublists
\$\endgroup\$
2
\$\begingroup\$

Julia 1.0, 33 30 25 bytes

l/b=b.|>a->splice!(l,1:a)

Try it online!

Thanks to dingledooper for -3 bytes and to MarcMush to further -5.

\$\endgroup\$
2
  • \$\begingroup\$ 30 bytes: l/b=(i=1;b.|>a->l[i:(i+=a)-1]) \$\endgroup\$ Aug 7 at 21:02
  • \$\begingroup\$ 25 bytes: l/b=b.|>a->splice!(l,1:a) \$\endgroup\$
    – MarcMush
    Aug 9 at 12:31
2
\$\begingroup\$

Husk, 5 bytes

CzR⁰³

Try it online!

CzR⁰³     # 5-byte program, but this is equivalent to
CzR⁰²²    # 6-byte program without the ³ shortcut to use the 1st argument twice
 z        # zip together
   ⁰²     # the lists of the 1st and 2nd arguments
  R       # by repeating arg2 the number of times given by arg1;
          # now use the lengths of this list of lists to
C    ²    # cut the list of the 2nd argument
\$\endgroup\$
1
\$\begingroup\$

MATL, 5 bytes

"@:&)

Inputs B, then L. Displays each sublist on a separate line.

Try it online!

Explanation

"      % Implicit input: numeric vector B. For each k in B
  @    %   Push k
  :    %   Range [1 2 ... k]
  &)   %   Two-ouput indexing. The first time this takes as implicit input
       %   the numeric vector L; in subsequent iterations it uses as input
       %   what remains of L. Pushes a smaller vector according to the
       %   specified indices, and another vector with the remaining entries
       % Implicit end. Implicit display stack
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.