Write a program that, given any 'n' number of strings of 'm' length, returns 'm' number of 'n'-length strings, with this condition:

Every new string should contains the letters at the same index of the others strings

For example, the first output string must contain the first letter of all the input strings, the second output string must contain the second letter of all the input strings, and so on.

Examples (the numbers under the letters are the indexes of the strings):

input: "car", "dog", "man", "yay"
        012    012    012    012
output: "cdmy", "aoaa", "rgny"
         0000    1111    2222

input: "money", "taken", "trust"
        01234    01234    01234
output: "mtt", "oar", "nku", "ees", "ynt"
         000    111    222    333    444

Assume that the input is correct everytime

Shortest bytes' code wins!


Since there are many programming languages, and there could be many possible solutions for each of them, I will post the shortest solution for each programming language and the user who provided it. Keep coding!


Thanks to user Dennis I inserted a snippet for the leaderboards.

var QUESTION_ID=85255,OVERRIDE_USER=56179;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

  • 2
    \$\begingroup\$ We have a leaderboard snippet that you can add to your question body. No need to do that by hand. \$\endgroup\$ – Dennis Jul 12 '16 at 16:49
  • \$\begingroup\$ Duplicate: codegolf.stackexchange.com/q/17305 \$\endgroup\$ – msh210 Jul 12 '16 at 18:06
  • \$\begingroup\$ I'm sorry, I didn't know it was called "transposing" \$\endgroup\$ – Input Name Here Jul 12 '16 at 19:01
  • 6
    \$\begingroup\$ I do not believe these challenges are duplicates, because of the differences involving ragged transposition and some weird whitespace handling in the other question. While in some languages the answers might be very similar, I think in most they will be different enough that this shouldn't be a duplicate. \$\endgroup\$ – FryAmTheEggman Jul 13 '16 at 12:40
  • \$\begingroup\$ Related, Related \$\endgroup\$ – FlipTack Dec 4 '17 at 20:37

26 Answers 26


Pyth, 1 byte


Try it here

Another transpose builtin

  • 5
    \$\begingroup\$ How is this even possible?! \$\endgroup\$ – DavidC Jul 12 '16 at 19:15
  • \$\begingroup\$ Surely you're joking! \$\endgroup\$ – Vincent Jul 12 '16 at 19:43
  • \$\begingroup\$ Pyth is the new Mathematica! \$\endgroup\$ – Loovjo Jul 12 '16 at 20:24

Python, 36 29 bytes

zip(*s) returns a list of tuples of each character, transposed.

lambda s:map(''.join,zip(*s))

Try it online

  • \$\begingroup\$ The output says "cdmy", "aoaa", "rgny", which is a list ["cdmy", "aoaa", "rgny"] or a tuple ("cdmy", "aoaa", "rgny") \$\endgroup\$ – mbomb007 Jul 12 '16 at 16:41
  • \$\begingroup\$ map(''.join,zip(*s)) also works for the string conversion (Python 2 only), and for Python 3, [*map(''.join,zip(*s))] afaik works \$\endgroup\$ – Value Ink Jul 12 '16 at 17:14
  • \$\begingroup\$ @KevinLau-notKenny map(''.join,zip(*s)) is valid for Python 3 also - we allow iterators/generators in place of lists by default. \$\endgroup\$ – Mego Jul 12 '16 at 21:35

Jelly, 1 byte


Try it online!


MATL, 1 byte


Try it online!

Takes input implicitly, transposes, displays output implicitly.


PowerShell v2+, 66 54 bytes


Yo ... no map, no zip, no transpose, etc., so we get to roll our own. Big props to @DarthTwon for the 12-byte golf.

Takes input $n, sets up a for loop. Initialization sets $x to 0, the test is whether we still have letters in our word $n[0][$x], and we increment $x++ each iteration.

Inside the loop, we take our array of strings, pipe it to an inner loop that spits out the appropriate character from each word. That is encapsulated in a -join to form a string, and that string is left on the pipeline. At end of execution, the strings on the pipeline are implicitly printed.

PS C:\Tools\Scripts\golfing> .\convert-n-strings.ps1 "Darth","-Twon","Rocks"
  • 1
    \$\begingroup\$ Nice, that's the kind of the answers I wanted to see ;) It's too simple writing , rather than thinking about the answer \$\endgroup\$ – Input Name Here Jul 12 '16 at 17:15
  • \$\begingroup\$ Using a while loop can further pare that down: param($n)$x=0;while($n[0][$x]){-join($n|%{$_[$x]});$x++}. And no errors here :D \$\endgroup\$ – ThePoShWolf Jul 12 '16 at 18:45
  • \$\begingroup\$ @DarthTwon Excellent. Or, use a for loop for another two. ;-) \$\endgroup\$ – AdmBorkBork Jul 12 '16 at 19:06
  • \$\begingroup\$ Hmm... I tried that, but not after really paring down my while loop. Good work sir! \$\endgroup\$ – ThePoShWolf Jul 12 '16 at 20:03
  • \$\begingroup\$ Can you use Linq in Powershell? \$\endgroup\$ – aloisdg Jul 20 '16 at 15:33

Vim, 37 36 keystrokes

All the other answers are boring, and using boring single-byte builtins. Here's a hacky answer that does the entire thing manually, in something that isn't even a programming language:



G                                   "move to the end of this line
     ma                             "And leave mark 'a' here
       qq                           "Start recording in register 'q'
         gg                         "Move to the beginning
           :s/./&<cr>               "Assert that there is atleast one character on this line
                      d             "Delete
                       <C-v>        "Blockwise
                            `a      "Until mark 'a'

    G                               "Move to the end of the buffer
     o<esc>                         "Open a newline below us
           p                        "And paste what we deleted
            vG                      "Visually select everything until the end
              gJ                    "And join these without spaces
                @q                  "Call macro 'q'. The first time, this will do nothing,
                                    "The second time, it will cause recursion.
                  q                 "Stop recording
                   @q               "Call macro 'q' to start it all

Now, everything is good, but the buffer has some extra text left over. So we must:

`a                              "Move to mark 'a'
  dgg                           "And delete everything until the first line

CJam, 6 5 bytes

Saved 1 byte thanks to Luis Mendo.


Try it online!

q      e# Get all input
 S%    e# Split it on spaces
   z   e# Take the transpose
    p  e# Print it as an array

Pyke, 1 byte


Try it here!


  • 1
    \$\begingroup\$ Oh... Didn't think it would have been so simple :/ \$\endgroup\$ – Input Name Here Jul 12 '16 at 16:32
  • 1
    \$\begingroup\$ Yeah, I can't seem to find a duplicate by looking for 60 secs though \$\endgroup\$ – Blue Jul 12 '16 at 16:34

Retina, 45 43 bytes

Byte count assumes ISO 8859-1 encoding.


The leading linefeed is significant. Input and output are linefeed-terminated lists of printable ASCII strings (note that both have a single trailing linefeed).

Try it online!

I knew for a while that transposing rectangular blocks would be a pain in Retina (whereas transposing squares isn't too bad), but never actually tried. The first solution was indeed a whopping 110 bytes long, but after several substantial changes in the approach, the resulting 45 bytes are by far not as bad as I suspected (but still...). Explanation will follow tomorrow.


Stage 1: Sort


This does the main work of reordering the characters in the input, but it ends up messing up the separation into lines. Interestingly, if we remove the , we get the code required to transpose a square input.

Sort stages (denoted by the O) work like this: they find all matches of the given regex (the thing after the `), and then sort those matches and reinsert them into the places where the matches were found. As it happens, this regex matches every single character: non-linefeeds via the .(?<=(.*)) alternative and linefeeds via the . Hence, it sorts all characters in the input. The more interesting part is what they are sorted by.

The $ option activates a "sort-by" mode, where each match is replaced with the substitution pattern on the second line, which is then used for comparing the matches. Furthermore, the # tells Retina to convert the result of the substitution to an integer, and compare those integers (instead of treating them as strings).

So finally, we need to look at the regex and the substitution. If the first alternative matches (i.e. we have matched any character within one of the lines), then the (?<=(.*)) captures everything up to that character on that line into group 1. The $.1 in the substitution pattern replaces this with the length of group 1. Hence, the first character in each string becomes 1, the second becomes 2, the third becomes 3 and so on. It should be clear now how this transposes a square input: all the first characters of the lines come first and all end up in the top-most line, then all the second characters end up in the second line and so on. But for these rectangular inputs, we're also matching the linefeeds. Since group 1 is unused in this case, the substitution is empty, but for the purposes of the # option, this is considered 0. That means, all the linefeeds are sorted to the front.

So now we do have the characters in the first order (first character of each string, second character of each string, etc.) and all the linefeeds at the start.

Stage 2: Match


We now need to split up the characters into lines of the correct length. This length corresponds to the number of lines in the original input, which is corresponds to the number of linefeeds we have at the beginning of the string.

The splitting is done here with the help of a match stage, which simply finds all matches of the given regex and uses the ! option to print those matches (the default would be to count them instead). So the goal of the regex is to match one line at a time.

We start by "counting" the number with the lookbehind (?<=(¶)*.*). It generates one capture in group 1 for every linefeed at the front.

Then, for each of those captures, we match a single character with (?<-1>.)+.


x86 machine code, 19 bytes

In hex:


Input: ECX: # of strings (n), EDX: individual string length (m), ESI: array of input strings, EDI: output buffer receiving array of strings. Array is presumed to be defined as char src[n][m+1] for input and char dst[m][n+1] for output, and all strings are NULL-terminated.

0:  fc                  cld
1:  89 d3               mov ebx,edx   ;EDX is the counter for the outer loop
3:  56                  push esi
4:  51                  push ecx
5:  a4                  movsb         ;[EDI++]=[ESI++]
6:  01 de               add esi,ebx   ;Same char, next string
8:  e2 fb               loop _inner   ;--ECX==0 => break
a:  91                  xchg eax,ecx  ;EAX=0
b:  aa                  stosb         ;NULL-terminate just completed string
c:  59                  pop ecx
d:  5e                  pop esi       ;First string,
e:  46                  inc esi       ;...next char
f:  4a                  dec edx
10: 75 f1               jnz _outer
12: c3                  ret

Brachylog, 5 bytes


Expects a list of strings as input, e.g. run_from_atom('z:ca.',["money":"taken":"trust"],Output).


z       Zip the strings in the Input list
 :ca.   output is the application of concatenation to each element of the zip

05AB1E, 3 bytes



     # implicit input, eg: ['car', 'dog', 'man', 'yay']
ø    # zip, producing [['c', 'd', 'm', 'y'], ['a', 'o', 'a', 'a'], ['r', 'g', 'n', 'y']]
 €J  # map join, resulting in ['cdmy', 'aoaa', 'rgny']

Try it online


CJam, 3 bytes


This is a code block (equivalent to a function; allowed by default) that expects the input on the stack and leaves the output on the stack.

Try it online!

  • \$\begingroup\$ Sure about that? \$\endgroup\$ – DJMcMayhem Jul 12 '16 at 19:00
  • 1
    \$\begingroup\$ @Drgreeneggsandironman Well, the answer with more votes says The default should be "programs or functions" \$\endgroup\$ – Luis Mendo Jul 12 '16 at 19:34

JavaScript ES6, 48 46 bytes


I feel left out, we have no built in zip function. Thanks nicael for pointing out my type error.


(a=>[...a[0]].map((n,x)=>a.map(a=>a[x])))(["asd","dsa"]); //or whatever is above, might change due to edits


  • \$\begingroup\$ Exception: TypeError: a[0].map is not a function \$\endgroup\$ – edc65 Jul 12 '16 at 16:48
  • 1
    \$\begingroup\$ You need [...a[0]].map, since a[0] isn't an array. \$\endgroup\$ – nicael Jul 12 '16 at 16:49
  • \$\begingroup\$ @nicael thanks. messed up the types. this proves why I should not golf this early in the morning. \$\endgroup\$ – charredgrass Jul 12 '16 at 16:50
  • \$\begingroup\$ @nicael I .joined them to fix that problem. \$\endgroup\$ – charredgrass Jul 12 '16 at 16:56
  • 1
    \$\begingroup\$ join`` instead of join('') to save 2 bytes. Downvote retracted \$\endgroup\$ – edc65 Jul 12 '16 at 17:39

Bash + BSD utilities, 27

sed s/./\&:/g|rs -c: -g0 -T

I/O via STDIN/STDOUT newline-separated strings.

You may need to install rs with sudo apt install rs or similar. Works out of the box on OS X.

The -T option to rs does the heavy lifting of the transposition. The rest is just formatting:

  • The sed command simply inserts : after every character
  • -c: specifies input columns are : separated
  • -g0 specifies output columns have zero width separation

If my reading of the rs manpage is correct, then the following ought to work for a score of 12, but unfortunately it doesn't work - see note below:

rs -E -g0 -T

Example output:

$ printf "%s\n" car dog man yay |sed s/./\&:/g|rs -c: -g0 -T

If input is expected to be all printable ASCII, then the : may be replaced with some unprintable character, e.g. 0x7 BEL.


I wanted to understand why I couldn't get the -E option to work and get rid of the sed preprocessing. I found the rs source code here. As you can see, giving this option sets the ONEPERCHAR flag. However, there is nothing in the code that actually checks the state of this flag. So I think we can say that despite the fact that is option is documented, it is not implemented.

In fact, this option is documented in the Linux rs manpage:

-E Consider each character of input as an array entry.

but not the OS X version.


PHP, 82 bytes

function f($a){foreach($a as$s)foreach(str_split($s)as$i=>$c)$y[$i].=$c;return$y;}

takes and returns an array of strings

break down

function f($a)
    foreach($a as$s)                    // loop through array $a
        foreach(str_split($s)as$i=>$c)  // split string to array, loop through characters
            $y[$i].=$c;                 // append character to $i-th result string


    ["asd","dsa"], ["ad","ss","da"],
    ["car", "dog", "man", "yay"], ["cdmy", "aoaa", "rgny"],
    ["money", "taken", "trust"], ["mtt", "oar", "nku", "ees", "ynt"]
echo '<pre>';
while ($samples)
    echo '<b>in:</b> ';         print_r($x=array_shift($samples));
    echo '<b>out:</b> ';        print_r(f($x));
    echo '<b>expected:</b> ';   print_r(array_shift($samples));
    echo '<hr>';

APL, 3 bytes


takes the input strings and turns them into a char matrix. transposes the matrix. splits back the rows of the resulting matrix into strings.


K, 1 byte


Try it here!



Mathematica, 26 bytes


Anonymous function. Takes a string list as input and returns a string list as output. The Unicode character is U+F3C7, representing \[Transpose]. Works by converting to a character matrix, transposing, and converting back to a string list. If the input/output format was stretched, then a simple 5-byte transpose would work:

  • \$\begingroup\$ +1 you beat me to the punch! (But I wasn't able to use the Transpose symbol.) By the way, why doesn't the T show up on screen? (It is there when I copy your code to Mathematica). \$\endgroup\$ – DavidC Jul 12 '16 at 19:27
  • \$\begingroup\$ @DavidC The Unicode character is in the Private Use Area, which is marked as a section for proprietary characters and is therefore neither officially assigned a glyph nor rendered at all in most fonts. Mathematica's font just happens to render this character as a supserscript T and interpret it as a \[Transpose]. \$\endgroup\$ – LegionMammal978 Jul 12 '16 at 19:52
  • \$\begingroup\$ @DavidC Why don't they use ? \$\endgroup\$ – Adám Jul 20 '16 at 15:13
  • \$\begingroup\$ @Adám IDK, you'd have to ask Wolfram Research about that, not me \$\endgroup\$ – LegionMammal978 Jul 20 '16 at 15:17
  • \$\begingroup\$ @LegionMammal978 Nah, I'm happy as long as I have APL's obvious . \$\endgroup\$ – Adám Jul 20 '16 at 15:43

MATLAB / Octave, 4 bytes


This defines an anonymous function. Input format is ['car'; 'dog'; 'man'; 'yay'].

Try it here.

  • \$\begingroup\$ What format is the input for this solution? I don't think it will work with the way Matlab handles strings if you try to input them in a Matlabby way, e.g. f = @(x)x', f([{'abcd'},{'abcd'},{'abcd'}]) outputs ans = 'abcd' 'abcd' 'abcd' \$\endgroup\$ – sintax Jul 13 '16 at 20:36
  • \$\begingroup\$ @sintax Input format should be a 2D char array, as in the example linked in the answer. You are using a cell array of strings (obtained by concatenating singleton cell arrays). It should be: f(['abcd';'abcd';'abcd']). I've edited the answer to specify the input format \$\endgroup\$ – Luis Mendo Jul 13 '16 at 21:42

Haskell, 41 bytes

f l=zipWith($)[map(!!n)|n<-[0..]]$l<$l!!0

Or with a bit more air:

f l = zipWith ($) [map (!! n) | n <- [0..]] $
                  l <$ (l !! 0)

The second list is the list of words repeated “the length of a word” time. On each list of words, we select the n-th letter of each word, giving the result.

  • 1
    \$\begingroup\$ There's no need for a full program, because "program" means "program or function", so a function is enough. You can pass and return a list of strings and therefore omit wordsand unwords. Further, map(\_->l)(l!!0) is l<*l!!0, so it boils down to \l->zipWith($)[map(!!n)|n<-[0..]]$l<$l!!0. \$\endgroup\$ – nimi Jul 13 '16 at 22:15
  • \$\begingroup\$ Oh, good thanks :) I'm updating. \$\endgroup\$ – villou24 Jul 13 '16 at 22:25
  • \$\begingroup\$ Oops, typo: it's l<$l!!0 (first time wrong, second time right), but you got it right anyway. \$\endgroup\$ – nimi Jul 13 '16 at 22:34

Common Lisp, 62 bytes

(lambda(s)(apply'map'list(lambda(&rest x)(coerce x'string))s))

The map function takes a result type (here list), a function f to apply and one or more sequences s1, ..., sn. All sequences are iterated in parallel. For each tuple of elements (e1,...,en) taken from those sequences, we call (f e1 ... en) and the result is accumulated in a sequence of the desired type.

We take a list of strings, say ("car" "dog" "man" "yay"), and use apply to call map. We have to do this so that the input list is used as more arguments to map. More precisely, this:

(apply #'map 'list fn '("car" "dog" "man" "yay"))

... is equivalent to:

(map 'list f "car" "dog" "man" "yay")

And since strings are sequences, we iterate in parallel over all first characters, then all second characters, etc... For example, the first iteration calls f as follows:

(f #\c #\d #\m #\y)

The anonymous lambda takes the list of arguments given to it and coerces it back to a string.


Perl, 91 bytes

So lengthy one..

$l=<>;$p=index($l," ")+1;@i=split//,$l;for$a(0..$p-1){print$i[$a+$_*$p]for(0..$p);print" "}

Try it here!


Ruby, 46 bytes

Probably the first time that "Ruby strings aren't Enumerables" is actually biting me hard since I had to map the strings into arrays before processing. (Normally having to use String#chars isn't enough of a byte loss to matter, but since I need to map them, it stings a lot more)

->s{s.map!(&:chars).shift.zip(*s).map &:join}

Clojure, 68 bytes

#(map(fn[g](reduce(fn[a b](str a(nth b g)))""%))(range(count(% 0))))

Maps a function which is just reduce (goes on elements of the list one by one and joins nth character of the string) on the range from 0 to length of the first string.

See it online: https://ideone.com/pwhZ8e


C#, 53 bytes


C# lambda (Func) where the output is IList<string> and the output is IEnumerable<string>. I dont know how work zip in other language but I can't find a way to use the C#'s one here. Aggregate fit the need well. No transpose in C#, there is one in Excel but I wont use it.

Try it online!


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.