27
\$\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\$ Commented Aug 7, 2021 at 1:21

31 Answers 31

11
\$\begingroup\$

Python 2, 39 bytes

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

Try it online!

\$\endgroup\$
11
\$\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\$
8
\$\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\$
7
\$\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\$ Commented Aug 7, 2021 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
    Commented Aug 7, 2021 at 1:58
  • \$\begingroup\$ ⍸⍛⊆ for 3 bytes \$\endgroup\$
    – ovs
    Commented Aug 7, 2021 at 8:50
  • \$\begingroup\$ @ovs oh wow that's so obvious now I think about it, thanks! \$\endgroup\$
    – rak1507
    Commented Aug 7, 2021 at 13:22
  • \$\begingroup\$ /⊸⊔ in BQN, character by character \$\endgroup\$
    – Razetime
    Commented Aug 7, 2021 at 15:40
6
\$\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\$
6
\$\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\$
6
\$\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\$
1
  • 1
    \$\begingroup\$ 29 \$\endgroup\$
    – l4m2
    Commented Mar 1, 2022 at 3:52
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
    Commented Aug 7, 2021 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 Wizard
    Commented Aug 7, 2021 at 19:11
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
    Commented Aug 7, 2021 at 11:57
6
\$\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
  • 2
    \$\begingroup\$ 25 bytes. (TakeList without the explicit arguments would work if it wasn't prohibited) \$\endgroup\$
    – att
    Commented Aug 7, 2021 at 2:44
5
\$\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\$ Commented Aug 9, 2021 at 3:00
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 Wizard
    Commented Aug 7, 2021 at 13:06
  • \$\begingroup\$ @WheatWizard Aha, thanks! I didn't realise that would cover the (c:[]) case too. \$\endgroup\$ Commented Aug 7, 2021 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\$

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\$

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
    Commented Aug 12, 2021 at 1:40
4
\$\begingroup\$

Vyxal, 2 bytes

ɾ•

Try it Online!

If generators weren't so broken, it'd just be vɾ• and flagless. Thank goodness for Vyxal 2.8 lol.

Explained

ɾ•
ɾ    # vectorise range for each item in the shape list
•   # and mold that to the shape list

So essentially, a port of hyper's jelly

\$\endgroup\$
2
  • \$\begingroup\$ Try it Online! might be a better link :) \$\endgroup\$ Commented Aug 7, 2021 at 1:36
  • \$\begingroup\$ Nice. Much better than my mess. \$\endgroup\$
    – emanresu A
    Commented Aug 7, 2021 at 1:36
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\$

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\$ Commented Aug 7, 2021 at 7:15
  • \$\begingroup\$ Ha, that's a lot better. Should have seen it. Thanks. \$\endgroup\$
    – Jonah
    Commented Aug 7, 2021 at 7:33
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\$
3
\$\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\$
3
\$\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\$
3
\$\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\$
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\$

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\$ Commented Aug 7, 2021 at 21:02
  • \$\begingroup\$ 25 bytes: l/b=b.|>a->splice!(l,1:a) \$\endgroup\$
    – MarcMush
    Commented Aug 9, 2021 at 12:31
2
\$\begingroup\$

PowerShell Core, 39 bytes

param($u,$v)$u|%{,$v[$s..(($s+=$_)-1)]}

Try it online!

Two test cases are not working because PowerShell flattens simple jagged arrays, i.e. [[7]] becomes [7]

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

Uiua, 5 3 bytes

⊕□⊚

Try it!

-2 thanks to Bubbler

⊕□⊚
  ⊚  # where
⊕□   # group with boxing
\$\endgroup\$
2
  • 1
    \$\begingroup\$ ⊕□⊚ works. Try it! \$\endgroup\$
    – Bubbler
    Commented Oct 16, 2023 at 1:44
  • \$\begingroup\$ @Bubbler Awesome. Thanks! \$\endgroup\$
    – chunes
    Commented Oct 16, 2023 at 2:06
2
\$\begingroup\$

Husk, 5 4 bytes

CmR¹

Try it online!

CmR¹      # 5-byte program, but this is equivalent to
CzR⁰⁰²    # 6-byte program using the ¹ shortcut to use the 1st arg twice and implicit 2nd arg
 m        # map over
   ⁰      # the list of the 1st argument
  R ⁰     # by repeating arg1 this number of times;
          # 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\$
1
\$\begingroup\$

Arturo, 36 bytes

$[a,b][map b'i[take a i a:drop a i]]

Try it

$[a,b][             ; a function taking two arguments a and b
  map b'i[          ; map over b and assign current elt to i
    take a i        ; the first i elts of a
    a:drop a i      ; assign a sans the first i elts to a
  ]                 ; end map
]                   ; end function
\$\endgroup\$
1
\$\begingroup\$

Nekomata, 4 bytes

J$ᶻL

Attempt This Online!

J$ᶻL    Input L and R
J       Non-deterministically split L into parts
 $      Swap to get R
  ᶻL    Check that the length of each part is equal to the corresponding element of R
\$\endgroup\$

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