# Interleave strings

Inspiration.* I cannot believe we have not had this challenge before:

Task

Given one or more printable ASCII strings, interleave them by taking one character from each string, cyclically until out of characters. If a string runs out of characters before the others, just skip that one from then on.

Examples

SIMPLE gives SIMPLE

POLLS and EPEES gives PEOPLELESS

LYES and APRONS gives LAYPERSONS

ABCDE and a c and 123 567 gives Aa1B 2Cc3D E567

"\n$?* and ​ (empty string) and ,(.)"  (trailing space) gives ",\(n.$)?"*  (trailing space)

* There are shorter APL solutions.

• Since this is basically just a transpose operation, we've had a few challenges that are very similar, but possibly none that are exactly the same. Commented Dec 8, 2016 at 12:10
• I had this question on my CS HW, does that mean I can close this as a homework question? ;P Commented Dec 8, 2016 at 14:40

# Jelly, 1 byte

Z


Try it online!

The “transpose” built-in will do exactly this to a list of strings.

• I'm curious, what would the code have looked like if you had to pad short strings with spaces?
– Adám
Commented Dec 8, 2016 at 13:33
• That would be z⁶. z is “transpose left, padding with right”; ⁶ is a space.
– lynn
Commented Dec 8, 2016 at 13:47
• @Adám Jelly works very well on lists; where do built-ins end and language constructs / design begin? Commented Dec 8, 2016 at 15:44
• @Lynn In Jelly? Anything on the Atoms and Quicks lists are buildt-ins.
– Adám
Commented Dec 8, 2016 at 16:08
• @Adám ;" (element-wise concatenation) would solve the task without a built-in. Commented Dec 8, 2016 at 17:04

# Python 2, 1018986 69 bytes

I'm hoping I can get this into a lambda somehow, shortening it down by making it recursive. It isn't ideal because you would hope transposing is shorter, unfortunately it isn't (from what I have managed to come up with so far).

f=lambda s:' '*any(s)and''.join(x[:1]for x in s)+f([x[1:]for x in s])


Old solutions:

w=input();o=''
while any(w):
for i in range(len(w)):o+=w[i][:1];w[i]=w[i][1:]
print o

lambda s:''.join(''.join([c,''][c<' ']for c in x)for x in map(None,*[list(y)for y in s]))

w=input();o=''
while any(x>=' 'for x in w):
for i in range(len(w)):o+=w[i][:1];w[i]=w[i][1:]
print o

thanks to mathmandan for making me feel dumb ;) saved me a bunch of bytes! (on an old solution)

• Couldn't you just do while any(w):? Empty strings are falsey in Python. Commented Dec 8, 2016 at 13:30
• @mathmandan You're absolutely right, don't know what I was thinking..
– Kade
Commented Dec 8, 2016 at 13:33
• No problem :) Your new solution looks great, except I think you need to prepend f=. Commented Dec 8, 2016 at 13:54
• You can take the [] off of the recursive call, leaving f(x[1:] for x in s), that makes it a generator comprehension, which acts the same as a list in this context. Commented Aug 1, 2017 at 17:37

## Perl 6, 34 32 bytes

{[~] flat roundrobin |$_».comb}  {roundrobin(|$_».comb).flat.join}


A lambda that takes an array of strings as argument, and returns a string.

• I would have used @_ instead of $_ Commented Dec 8, 2016 at 19:13 ## CJam, 4 bytes qN/z  Try it online! We can also write an unnamed function for 4 bytes, which expects a list of strings on top of the stack: {zs}  Try it online! • That's one byte a minute! – Adám Commented Dec 8, 2016 at 12:12 # Pyth - 3 bytes Very simple, will add expansion later, on mobile. s.T  Test Suite s Join all the strings together .T Transpose, without chopping off overhang (Q implicit)  • @Daniel I'm in school too :P Commented Dec 8, 2016 at 14:31 • Any plans on adding the explanation? Commented Apr 14, 2017 at 14:14 • @JanDvorak sure doing it now. Commented Apr 16, 2017 at 0:17 # J, 13 bytes ({~/:)&;#\&.>  Try it online! Based on the inspiration for this question. Another way to do it takes 27 bytes but operates using transpose. Most of the bytes are to handle the automatically added zeroes from padding. [:u:0<:@-.~[:,@|:(1+3&u:)&>  ## Explanation ({~/:)&;#\&.> Input: list of boxed strings S &.> For each boxed string x in S #\ Get the length of each prefix from shortest to longest This forms the range [1, 2, ..., len(x)] Rebox it ( ) Operate on S and the prefix lengths &; Raze both /: Grade up the raze of the prefix lengths {~ Index into the raze of S using the grades Return  • J's prohibiting mixed arrays really hurts you here. Try it in APL. – Adám Commented Dec 8, 2016 at 15:11 • Very nice approach. You can do the transpose approach in 15 bytes without worrying about 0 like this: [:u:@,@|:3&u:&>. TIO Commented Aug 23, 2022 at 23:02 • 8 years later... I think ({~/:) is exactly what dyadic /: does – ovs Commented Jun 28 at 10:20 # JavaScript (ES6), 52 46 bytes f=([[c,...s],...a])=>s+a?c+f(s+s?[...a,s]:a):c  Takes input as an array of strings and outputs as a single string. ### Test snippet f=([[c,...s],...a])=>s+a?c+f(s+s?[...a,s]:a):c g=a=>console.log("Input:",JSON.stringify(a),"Output:",JSON.stringify(f(a))) g(["SIMPLE"]) g(["POLLS","EPEES"]) g(["LYES","APRONS"]) g(["ABCDE","a c","123 567"]) g(["\"\\n$?*",",(.)\" "]) // Backslash and quote are escaped, but in/output are correct

• f=([[c,...s],...a])=>c?c+f([...a,s]):a+a&&f(a)
– Neil
Commented Dec 8, 2016 at 14:06
• @Neil That's a great approach. I managed to golf 6 bytes off my own :-) Commented Dec 8, 2016 at 15:35

# Haskell, 33 bytes

import Data.List
concat.transpose


Try it on Ideone. Usage:

Prelude Data.List> concat.transpose$["ABCDE","a c","123 567"] "Aa1B 2Cc3D E567"  ### Without using a build-in: (38 34 bytes) f[]=[] f x=[h|h:_<-x]++f[t|_:t<-x]  Try it on Ideone. 4 bytes off thanks to Zgarb! Usage: Prelude> f["ABCDE","a c","123 567"] "Aa1B 2Cc3D E567"  • You can remove all parens in the alternative version. Still won't beat the import though. Commented Dec 8, 2016 at 16:46 • Do you actually need the base case? – xnor Commented Dec 8, 2016 at 17:16 • Never mind, of course the base case is needed. – xnor Commented Dec 8, 2016 at 17:24 • @xnor You also can't move the base case to the end and replace it with f a=a to save a byte because both [] have a different type ... so close. Commented Dec 8, 2016 at 19:46 # C, 114 84 bytes -20 bytes for not calculating the length. i,b;f(char**s){b=1;while(b){i=-1;b=0;while(s[++i]>0)if(*s[i])putchar(*s[i]++),++b;}}  Accepts array of char pointers and requires last item to be a null-pointer (see usage). Ungolfed and usage: i,b;f(char**s){ b=1; while(b){ i=-1; b=0; while(s[++i]>0) if(*s[i]) putchar(*s[i]++),++b; } } int main(){ char*a[]={ // "POLLS","EPEES" // "LYES","APRONS" "ABCDE","a c","123 567" ,0}; f(a); puts(""); }  • Does the usage of printf/sprintf not allowed ? :D you would win quite some bytes. Commented Dec 8, 2016 at 14:18 • @Walfrat Without printing directly I'd need to allocate a string, so how could this save anything. Commented Dec 8, 2016 at 14:22 • it was before your edit where you added the ++b and remove length compute, so yes can't work anymore. Commented Dec 8, 2016 at 14:26 • @Walfrat Yes, but i had a malloc and return before and this was longer than just printing Commented Dec 10, 2016 at 18:50 # PHP, 68 67 bytes for(;$f=!$k=$f;$i++)for(;y|$v=$argv[++$k];$f&=""==$c)echo$c=$v[$i];  Loops over command line arguments. Run with -r. After the inner loop, $f is 1 when all strings are finished, 0 else (bitwise & casts ""==$c to int). Next iteration of the outer loop: copy $f to $k (saves one byte from $k=0) and toggle $f: When all strings are done, $f is now false and the loop gets broken.

• Doesn't work with empty input strings. Take a look at the last testcase Commented Dec 9, 2016 at 11:01
• @aross: fixed. thanks. Commented Dec 9, 2016 at 14:26

## Retina, 13 bytes

Byte count assumes ISO 8859-1 encoding.

O$#.$.%
¶



Try it online!

### Explanation

O$#.$.%


This is based on the standard transposition technique in Retina. We sort (O) all non-linefeed characters (.), by ($#) the number of characters in front of them on the same line ($.%), i.e. their horizontal position.

The second stage then simply removes linefeeds from the input.

## JavaScript (ES6), 46 bytes

f=([[c,...s],...a])=>c?c+f([...a,s]):a+a&&f(a)
<textarea oninput=o.textContent=f(this.value.split\n)></textarea><div id=o>

# Java, 19+155=174 160

String f(java.util.Queue<String> q){String s,r="";while(!q.isEmpty()){s=q.poll();r+=s.isEmpty()?"":s.charAt(0);if(s.length()>1)q.add(s.substring(1));}return r;}


Ungolfed:

  String f(java.util.Queue<String> q) {
String s, r = "";
while (!q.isEmpty()) {
s = q.poll();
r += s.isEmpty() ? "" : s.charAt(0);
if (s.length() > 1) {
q.add(s.substring(1));
}
}
return r;
}


Output:

SIMPLE

PEOPLELESS

LAYPERSONS

Aa1B 2Cc3D E567

",(n.$)?"* ​ First modification: merged string declaration to save some bytes. Removed import, it was used by the main() method (not shown here) that also needed LinkedList. It is fewer bytes to referece Queue directly. • initialize string s with string r can save few more Commented Dec 9, 2016 at 11:10 • I know it's been almost a year ago, but you can golf a few bytes: String f(java.util.Queue<String>q){String s,r="";for(;!q.isEmpty();r+=s.isEmpty()?"":s.charAt(0))if((s=q.poll()).length()>1)q.add(s.substring(1));return r;} Commented Sep 6, 2017 at 8:55 # Python 2, 58 bytes lambda*m:''.join(map(lambda*r:''.join(filter(None,r)),*m))  Try it online! • Can't you remove the space in lambda *m? Commented Apr 16, 2017 at 6:50 • I just did that! Thank you! Commented Apr 16, 2017 at 6:56 # PHP, 77 bytes ## Golfed function($a){for($d=1;$d!=$s;$i++){$d=$s;foreach($a as$v)$s.=$v[$i];}echo$s;}


Anonymous function that takes an array of strings.

I'm sure this could be golfed more, but it's early. On each iteration, we grab the i-th letter from each given string and append it to our final string, one at a time. PHP just throws warnings if we access bits of strings that don't exist, so that's fine. We only stop when no changes have been made after looping through all the strings once.

I feel like the usage of $d can be golfed more, but it's early. :P • How exactly do you put an array of strings in a single argument? Commented Dec 8, 2016 at 13:50 • @Titus. Y'know, I never really thought about it. I just kinda assumed you could. Commented Dec 8, 2016 at 13:58 # Actually, 7 6 bytes Golfing suggestions welcome! Try it online! Edit: -1 byte thanks to Teal pelican. a Z♂ΣΣ  Ungolfing  Implicit input each string. a Invert the stack so that the strings are in the correct order. <space> Get the number of items on the stack, len(stack). Z Zip all len(stack) strings into one, transposing them. ♂Σ sum() every transposed list of chars into strings. Σ sum() again to join the strings together.  • Can you not remove the # to make it 6 bytes? Commented Dec 8, 2016 at 15:44 • @Tealpelican Welp, now I'm going to have to dig through all of my old Actually answers and see if I can't change Z♂#Σ to Z♂Σ in all of them. Thanks for the tip :D Commented Dec 8, 2016 at 15:49 • First time looking into the language, it looks so much fun! Glad I could help :)) Commented Dec 8, 2016 at 15:54 # Python 3, 59 bytes f=lambda s:s and s[0][:1]+f(s[1:]+[s[0][1:]][:s[0]>""])or""  A recursive function that takes a list of strings and returns a string. Try it online! ### Explanation We're going to build the interleaved string one character at a time. There are several cases to consider: • Is the first string in the list nonempty? Take its first character, move the rest of it to the end of the list, and recurse. • Is the first string in the list empty? Remove it from the list and recurse. • Is the list of strings empty? Then we're done. Return empty string. The implementation goes as follows: f = lambda s: s and ... or ""  Define f to be a function of one argument, s, which is a list of strings. If s is nonempty, do the ... part (see below); otherwise, return "". s[0][:1] + f(...)  Since we now know s is nonempty, we can refer to its first element, s[0]. We don't know yet whether s[0] is empty, though. If it isn't, we want to concatenate its first character to a recursive call; if it is, we can concatenate the empty string to a recursive call. Slicing everything left of index 1 works in both cases. s[1:] + ...  The argument to the recursive call is going to be all but the first element of s, concatenated to either a 1-element list (the rest of s[0] if it was nonempty) or an empty list (if s[0] was empty). [s[0][1:]][:s[0] > ""]  We put s[0][1:] (the part of s[0] after the first character, which is the empty string if s[0] is empty) into a singleton list and then take a slice of that list. If s[0] is empty, s[0] > "" is False, which is treated as 0 in a slice; thus, we slice from index 0 to index 0--an empty slice. If s[0] is not empty, s[0] > "" is True, which is treated as 1; thus, we slice from index 0 to index 1--the whole 1-element list. If lists of single-character strings can be used in place of strings, this solution can be 54 bytes: f=lambda s:s and s[0][:1]+f(s[1:]+(s[0]and[s[0][1:]]))  Try it online! # K (ngn/k), 13 bytes <!/,/'(!#:)'\  Try it online! Port of miles's J and DLosc's BQN. For a language with flatten and grade/sort-by but not zip-longest, I guess this is one of the best possible approaches. More straightforward port would be {(,/x)@<,/!'#'x} because K doesn't have fork or over. But it is possible to use K train by abusing repeat-scan: <!/,/'(!#:)'\ ( )'\ Given a list of strings, apply this to each list until convergence and collect all intermediate values (including the input): !#: get the indices of the list This always converges after step 1, giving (x;!#x) ,/' Flatten each <!/ Sort first by second  # Elisp, 242 Bytes This is literally my first time so it could probably be smaller and it only works with two arguments (assigned to a and b) (setq a (elt argv 0))(setq b (elt argv 1))(with-temp-buffer (insert a b)(setq i 0)(ignore-errors (while (< i (length b))(progn (goto-char (+(length a) 2 i))(transpose-chars (* -1 (- (length a) i 1)))(setq i (+ i 1)))))(princ (buffer-string)))  Ungolfed version (setq a (elt argv 0)) (setq b (elt argv 1)) (with-temp-buffer (insert a b) (setq i 0) (ignore-errors (while (< i (length b)) (progn (goto-char (+(length a) 2 i)) (transpose-chars (* -1 (- (length a) i 1))) (setq i (+ i 1)) ) ) ) (princ (buffer-string)) )  But if you strip away all the boilerplate code its actually much shorter (134). (insert a b) (setq i 0) (while (< i (length b)) (goto-char (+(length a) 2 i)) (transpose-chars (* -1 (- (length a) i 1))) (setq i (+ i 1)) )  Elisp really sucks. Someone needs to modify it for golfing if haven't already. • Welcome to the site and nice first golf! To improve the byte count you could have a look at our Tips for golfing in Lisp section: codegolf.stackexchange.com/questions/79719/…. Commented Jun 29 at 5:37 # Bash + GNU utilities, 55  eval paste sed "s/.*/<(fold -1<<<'&')/g"|tr -d \\n\\t  I/O via STDIN (line-separated) and STDOUT. The sed formats each line to a bash process substitution. These are then evaled into paste to do the actual interleaving. tr then removes unnecessary newlines and tabs. Ideone. # PHP, 63 bytes Note: uses IBM-850 encoding for(;$s^=1;$i++)for(;n|$w=$argv[++$$i];s&=x<~■)echox=w[i];  Run like this: php -r 'for(;s^=1;i++)for(;n|w=argv[++$$i];$s&=$x<~■)echo$x=$w[$i];' "\"\n\$?*" "" ",(.)\" " 2>/dev/null;echo > ",\(n.$)?"*


# Explanation

for(                       # Iterate over string index.
;
$s ^= 1; # Continue until$s (stop iterating) is 1.
# Flip $s so each iteration starts with$s
# being 1.
$i++ # Increment string index. ) for( ; "n" |$w=$argv[++$$i]; # Iterate over all input strings. OR with "n" # to allow for empty strings. s &= x<~■ # If last character printed was greater than # \x0 (all printable chars), set s to 0, # causing the loop to continue. ) echo x = w[i]; # Print char i of current string.  • IBM-850?! Is that a natural encoding for PHP? – Adám Commented Dec 9, 2016 at 11:48 • @Adám what do you mean by "natural"? PHP treats bytes in the range 128-255 as text, which is therefore interpreted as a constant. If the constant is undefined, it will be interpreted as a string. It's so I can do ~■ (negated binary 254) instead of "\x1" (binary 1). Commented Dec 9, 2016 at 13:02 • I see. It isn't that you actually need that codepage, you just need a 254 byte. – Adám Commented Dec 9, 2016 at 14:13 • @Adám yes, the codepage just makes it a printable char which is a little less annoying. Commented Dec 9, 2016 at 14:27 • Great use of $$! Commented Dec 9, 2016 at 14:29 # Python 3, 75 Bytes I know the other Python one is shorter, but this is the first time I've used map ever in my life so I'm pretty proud of it lambda n:''.join(i[k]for k in range(max(map(len,n)))for i in n if len(i)>k)  ## Python 2, 128 96 I was hoping not to have to use itertools a=lambda a:"".join([i for i in reduce(lambda: b,c:b+c, map(None,*map(lambda m:list(m),a)) if i])  Ungolfed  a=lambda a: #Start a lambda taking in a "".join( #Join the result together with empty string [i for i in reduce( #For every item, apply the function and 'keep' lambda: b,c:b+c, #Add lists from... map(None,*map( #None = Identity function, over a map of... lambda m:list(m), a) #list made for mthe strings m ) if i #truthy values only (otherwise the outer map will padd with None. ])  • Would appreciate feedback/advice on improving this. Commented Dec 9, 2016 at 16:51 • Looks like this answer is invalid due to some syntax errors. Here's a fixed version, and here's one possible way to golf it (58 bytes). Commented Jan 29, 2022 at 18:11 • @DLosc thanks! Not sure how best to incorporate those right now, but I appreciate it. Commented Jan 29, 2022 at 18:24 # R, 73 bytes for(i in 1:max(nchar(s<-scan(,""))))for(j in seq(s))cat(substr(s[j],i,i))  Try it online! Explanation: very simple (but verbose), just loop through printing ith character of the jth string. Fortunately, substr returns an empty string if given an out-of-range input. • I know, it has been a while since 2017 :), but still, you wouldn't need a for-loop when using substring, since it is vectorized: 65 bytes Commented Jun 27 at 8:30 • ... and by removing the internal for-loop only it is even possible to achieve 61 bytes! Commented Jun 27 at 8:42 • Nice suggestion, thanks! (Not that it matters, but I think the 65 byte version would need some tweaking as it wouldn't generalise to other numbers of inputs.) Commented Jun 27 at 11:20 • Alright, there should be length(s) instead of 3, of course, which makes exactly 73 bytes. Whatever - the other suggestion is still shorter... Commented Jun 27 at 12:56 # Perl 5, + -0n 24 bytes 1while s/^./!print$&/gem


Try it online!

## Explanation

-0n slurps the input into \$_ and repeatedly replaces the first char of each line with the result of negating the print of each match (which is the empty string since print returns 1 by default)

• I thought I was good in Perl, but this baffled me. So -0 on input that doesn't contail a NUL is equivalent to slurping all. And then ^. with /g prints each beginning of line, while replacing it with nothing. Commented Jan 29, 2022 at 9:36
• @Daniel Yeah that's about it! Needing to negate the print is a little annoying... Having looked at this again, I can save a byte using 1while s/.... so thanks! Commented Jan 29, 2022 at 16:10

# Factor, 22 bytes

[ round-robin ""like ]


Try it online!

# Pip, 3 bytes

WVg


Try it online!

The WV (weave) builtin does exactly this. It's commonly used as a binary operator to weave two iterables together, but it can also be used as a unary operator to weave a list of iterables together. Here, g is the list of command-line arguments.

# BQN, 23 10 bytes

Massive savings by porting miles's J solution

↕∘≠¨⍋⊸⊏○∾⊢


Anonymous tacit function that takes a list of strings and returns a string. Try it at BQN online!

### Explanation

↕∘≠¨⍋⊸⊏○∾⊢
¨         For each string in the argument list:
≠            Take its length
↕∘             and make a range from 0 to that number (exclusive)
With that list of lists of indices as the left argument
⊢  and the original list of lists of strings as the right argument:
○∾     Flatten both lists
⊸⊏       Index into the flattened string using
⍋          the grade-up of the flattened list of indices


Grade up, for those unfamiliar with APL-related languages, is an operation that takes a list and returns a permutation of its indices, such that if the items in the list were reordered according to the order of the indices, the list would become sorted ascending. For example:

Indices:  0 1 2 3 4 5
List:     3 1 4 1 5 9

Grade up: 1 3 0 2 4 5
Sorted:   1 1 3 4 5 9


This operation is useful for sorting one list according to the values of another list, as seen in the above solution.

# UiuaSBCS, 9 bytes

⊏⍏∩/◇⊂⍚°⊏


Try it!

### Explanation

⊏⍏∩/◇⊂⍚°⊏­⁡​‎‎⁪⁡⁪⁠⁪⁢⁣⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁤⁪‏⁠‎⁪⁡⁪⁠⁪⁣⁡⁪‏‏​⁡⁠⁡‌⁢​‎‎⁪⁡⁪⁠⁪⁣⁪‏⁠‎⁪⁡⁪⁠⁪⁤⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁡⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁢⁪‏‏​⁡⁠⁡‌⁣​‎‎⁪⁡⁪⁠⁪⁢⁪‏‏​⁡⁠⁡‌⁤​‎‎⁪⁡⁪⁠⁪⁡⁪‏‏​⁡⁠⁡‌­
⍚°⊏  # ‎⁡get list of length-ranges of input
∩/◇⊂     # ‎⁢flatten both ranges and input
⍏         # ‎⁣get rise (grade up) of flattened ranges
⊏          # ‎⁤index into input


Port of miles' J solution.

# Go, 140 bytes

func(s[]string)(o string){for L,e,i,k:=len(s),0,0,0;e!=L;i++{
r:=s[i%L]
if len(r)<=k{e++;continue}
o+=r[k:k+1]
if i%L==L-1{k++;e=0}}
return}


Attempt This Online!

### Explanation

func(s[]string)(o string){
for L,e,i,k:=len(s),0,0,0;e!=L;i++{ // loop while the the whole slice is not "empty"
j:=i%L // get the index of the string to look at
r:=s[j] // the string to try to take from
if len(r)<=k{e++;continue} // if the current k-index is farther along than the string's length, skip it
o+=r[k:k+1] // add the first character of the string to the output
if j==L-1{k++;e=0}} // move to the next character and reset the "empty" counter if at the end of the slice
return}
`