Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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. ** Ignore the Zero Width Spaces which have been included for proper rendering.

share|improve this question
    
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. – Martin Ender 14 hours ago
3  
I had this question on my CS HW, does that mean I can close this as a homework question? ;P – Downgoat 11 hours ago

18 Answers 18

up vote 15 down vote accepted

Jelly, 1 byte

Z

Try it online!

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

share|improve this answer
    
I'm curious, what would the code have looked like if you had to pad short strings with spaces? – Adám 13 hours ago
1  
That would be z⁶. z is “transpose left, padding with right”; is a space. – Lynn 12 hours ago
1  
@Adám Jelly works very well on lists; where do built-ins end and language constructs / design begin? – steenbergh 10 hours ago
1  
@Lynn In Jelly? Anything on the Atoms and Quicks lists are buildt-ins. – Adám 10 hours ago
1  
@Adám ;" (element-wise concatenation) would solve the task without a built-in. – Dennis 9 hours ago

Pyth - 3 bytes

Very simple, will add expansion later, on mobile.

s.T

Test Suite

share|improve this answer
3  
+1 for golfing from mobile! – Daniel 12 hours ago
2  
@Daniel I'm in school too :P – Maltysen 12 hours ago

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!

share|improve this answer
2  
That's one byte a minute! – Adám 14 hours ago

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.

(Try it online)

share|improve this answer
    
I would have used @_ instead of $_ – Brad Gilbert b2gills 7 hours ago

Python 2, 101 89 86 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)

share|improve this answer
    
Couldn't you just do while any(w):? Empty strings are falsey in Python. – mathmandan 13 hours ago
    
@mathmandan You're absolutely right, don't know what I was thinking.. – Kade 12 hours ago
    
No problem :) Your new solution looks great, except I think you need to prepend f=. – mathmandan 12 hours ago

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("");
}
share|improve this answer
    
Does the usage of printf/sprintf not allowed ? :D you would win quite some bytes. – Walfrat 12 hours ago
    
@Walfrat Without printing directly I'd need to allocate a string, so how could this save anything. – Karl Napf 12 hours ago
    
it was before your edit where you added the ++b and remove length compute, so yes can't work anymore. – Walfrat 12 hours ago

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"
share|improve this answer
1  
You can remove all parens in the alternative version. Still won't beat the import though. – Zgarb 9 hours ago
    
Do you actually need the base case? – xnor 9 hours ago
    
Never mind, of course the base case is needed. – xnor 9 hours ago
    
@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. – Laikoni 6 hours ago

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.

share|improve this answer

PHP, 68 bytes

for(;$f=!$k=$f;$i++)for(;""<$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.

share|improve this answer

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

share|improve this answer
    
f=([[c,...s],...a])=>c?c+f([...a,s]):a+a&&f(a) – Neil 12 hours ago
    
@Neil That's a great approach. I managed to golf 6 bytes off my own :-) – ETHproductions 10 hours ago

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.
share|improve this answer
    
Can you not remove the # to make it 6 bytes? – Teal pelican 10 hours ago
    
@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 – Sherlock9 10 hours ago
    
First time looking into the language, it looks so much fun! Glad I could help :)) – Teal pelican 10 hours ago

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>

share|improve this answer

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

share|improve this answer
    
How exactly do you put an array of strings in a single argument? – Titus 12 hours ago
    
@Titus. Y'know, I never really thought about it. I just kinda assumed you could. – Xanderhall 12 hours ago

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
share|improve this answer
    
J's prohibiting mixed arrays really hurts you here. Try it in APL. – Adám 11 hours ago

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.

share|improve this answer

C, 75 71 bytes

Only limitation is the output length. Currently it's 99, but can be easily stretched to 999 (+1 byte).

i;main(a,b)char**b;{a--;for(;i<99;i++)*b[i%a+1]&&putchar(*b[i%a+1]++);}

Ungolfed:

i;
main( a, b )
char **b;
{
    a--;
    for( ; i < 99; i++ )
        *b[i % a + 1] && putchar( *b[i % a + 1]++ );
}
share|improve this answer

Python, 112 bytes

i=len(x)if len(x)>len(y) else len(y) h=0 a="" while h<i: if h<len(x) a+=x[h] if h<len(y): a += y[h] h+=1 print a
share|improve this answer
5  
Your formatting is really messed up.. where do you even get x and y from? – Kade 12 hours ago

Java, 19+155=174

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

Ungolfed:

import java.util.*;

  String f(Queue<String> q) {
    String r = "";
    while (!q.isEmpty()) {
      String s = q.poll();
      r += s.isEmpty() ? "" : s.charAt(0);
      if (s.length() > 1) {
        q.add(s.substring(1));
      }
    }
    return r;
  }
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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