Sign up ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Given a list of strings, output a single string formed by taking a character from each string at each position, sorting them by ASCII ordinal, and appending them in order to the output string. In other words, for n input strings, the first n characters of the output will be the first characters of each of the inputs sorted by ordinal, the second n characters of the output will be the second characters of each of the inputs sorted by ordinal, and so on. You may assume that the strings are all of equal length, and that there will be at least one string. All strings will be composed of only ASCII printable characters (ordinals 32-127).

Reference implementation in Python (try it online):

def stringshuffle(strings):
  res = ''
  for i in range(len(strings[0])):
    res += ''.join(sorted([s[i] for s in strings],key=ord))
  return res

Examples:

"abc","cba" -> "acbbac"
"HELLO","world","!!!!!" -> "!Hw!Eo!Lr!Ll!Od"

Rules

  • Standard loopholes are forbidden
  • This is , so shortest answer in bytes wins

Leaderboard

The Stack Snippet at the bottom of this post generates the leaderboard from the answers a) as a list of shortest solution per language and b) as an overall leaderboard.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

## Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

## Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

## Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the snippet:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes

<style>body { text-align: left !important} #answer-list { padding: 10px; width: 290px; float: left; } #language-list { padding: 10px; width: 290px; float: left; } table thead { font-weight: bold; } table td { padding: 5px; }</style><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="language-list"> <h2>Shortest Solution 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> <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> <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><script>var QUESTION_ID = 64526; var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe"; var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk"; var OVERRIDE_USER = 45941; var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page; function answersUrl(index) { return "https://api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER; } function commentUrl(index, answers) { return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER; } function getAnswers() { jQuery.ajax({ url: answersUrl(answer_page++), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { answers.push.apply(answers, data.items); answers_hash = []; answer_ids = []; data.items.forEach(function(a) { a.comments = []; var id = +a.share_link.match(/\d+/); answer_ids.push(id); answers_hash[id] = a; }); if (!data.has_more) more_answers = false; comment_page = 1; getComments(); } }); } function getComments() { jQuery.ajax({ url: commentUrl(comment_page++, answer_ids), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { data.items.forEach(function(c) { if (c.owner.user_id === OVERRIDE_USER) answers_hash[c.post_id].comments.push(c); }); if (data.has_more) getComments(); else if (more_answers) getAnswers(); else process(); } }); } getAnswers(); var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/; var OVERRIDE_REG = /^Override\s*header:\s*/i; function getAuthorName(a) { return a.owner.display_name; } function process() { var valid = []; answers.forEach(function(a) { var body = a.body; a.comments.forEach(function(c) { if(OVERRIDE_REG.test(c.body)) body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>'; }); var match = body.match(SCORE_REG); if (match) valid.push({ user: getAuthorName(a), size: +match[2], language: match[1], link: a.share_link, }); else console.log(body); }); valid.sort(function (a, b) { var aB = a.size, bB = b.size; return aB - bB }); var languages = {}; var place = 1; var lastSize = null; var lastPlace = 1; valid.forEach(function (a) { if (a.size != lastSize) lastPlace = place; lastSize = a.size; ++place; var answer = jQuery("#answer-template").html(); answer = answer.replace("{{PLACE}}", lastPlace + ".") .replace("{{NAME}}", a.user) .replace("{{LANGUAGE}}", a.language) .replace("{{SIZE}}", a.size) .replace("{{LINK}}", a.link); answer = jQuery(answer); jQuery("#answers").append(answer); var lang = a.language; lang = jQuery('<a>'+lang+'</a>').text(); languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang.toLowerCase(), user: a.user, size: a.size, link: a.link}; }); var langs = []; for (var lang in languages) if (languages.hasOwnProperty(lang)) langs.push(languages[lang]); langs.sort(function (a, b) { if (a.lang_raw > b.lang_raw) return 1; if (a.lang_raw < b.lang_raw) return -1; return 0; }); for (var i = 0; i < langs.length; ++i) { var language = jQuery("#language-template").html(); var lang = langs[i]; language = language.replace("{{LANGUAGE}}", lang.lang) .replace("{{NAME}}", lang.user) .replace("{{SIZE}}", lang.size) .replace("{{LINK}}", lang.link); language = jQuery(language); jQuery("#languages").append(language); } }</script>

share|improve this question

17 Answers 17

GS2, 4 bytes

*Ü■/

This reads the strings from STDIN, separated by linefeeds.

The source code uses the CP437 encoding.

Test run

$ xxd -r -ps <<< '2a 9a fe 2f' > zip-sort.gs2
$ echo -e 'HELLO\nworld\n!!!!!' | gs2 zip-sort.gs2 
!Hw!Eo!Lr!Ll!Od

How it works

*       Split the input into the array of its lines.
 Ü      Zip the resulting array.
  ■     Map the rest of the program over the resulting array.
   /        Sort.
share|improve this answer

CJam, 5 bytes

q~z:$

Try it here.

share|improve this answer
1  
I beat you by like 14 seconds ;P. – Maltysen 17 hours ago

Pyth, 5 bytes

Zips(C) the input(Q), Maps Sort, then sums.

sSMCQ

Try it online.

share|improve this answer

JavaScript (ES6), 57 bytes

a=>a[0].replace(/./g,(c,i)=>a.map(w=>w[i]).sort().join``)
share|improve this answer

TeaScript, 9 bytes

_t¡ßlp¡)µ

TeaScript has all the right built-ins implemented in all the wrong ways.

Try it online

Ungolfed

_t()m(#lp())j``

Explanation

_t()        // Transposes input array
    m(#     // Loops through inputs
       lp() // Sorts characters by char code
     )
j``         // Joins back into string
share|improve this answer
    
@intrepidcoder works fine for me. Perhaps your browser has cached some files? Perhaps clearing your cache might work. I'm using Safari though. I'll try refreshing the files – Vɪʜᴀɴ 16 hours ago
    
That fixed it, thanks. – intrepidcoder 15 hours ago

Python, 50 48 bytes

lambda x,y=''.join:y(map(y,map(sorted,zip(*x))))

Thanks to @xnor for -2 bytes!

share|improve this answer
1  
You can save "".join to a variable. – xnor 16 hours ago
    
Oh, I had no idea. Thanks! – Dennis 16 hours ago

Octave, 15 bytes

@(a)sort(a)(:)'

Example:

octave:1> (@(a)sort(a)(:)')(["abc";"cba"])
ans = acbbac
octave:2> (@(a)sort(a)(:)')(["HELLO";"world";"!!!!!"])
ans = !Hw!Eo!Lr!Ll!Od
share|improve this answer

Julia, 46 bytes

x->(j=join)(map(i->j(sort([i...])),zip(x...)))

This creates an unnamed function that accepts an array of strings and returns a string. To call it, give it a name, e.g. f=x->....

Ungolfed:

function zipsort{T<:AbstractString}(x::Array{T,1})
    # Splat the input array and zip into an iterable
    z = zip(x...)

    # For each tuple consisting of corresponding characters
    # in the input array's elements, splat into an array,
    # sort the array, and join it into a string
    m = map(i -> join(sort([i...])), z)

    # Take the resulting string array and join it
    return join(m)
end
share|improve this answer

Haskell, 39 36 bytes

import Data.List
(>>=sort).transpose

Usage example: ((>>=sort).transpose) ["HELLO","world","!!!!!"] -> "!Hw!Eo!Lr!Ll!Od".

Transpose the list of strings, map sort over it and concatenate the resulting list of strings (>>= in list context is concatMap).

share|improve this answer
    
i came up with exactly this! – proud haskeller 13 mins ago

Minkolang 0.13, 46 bytes

$od0Z2:$zIz:$xd0G2-[i1+z[di0c*+c$r]xz$(sr$Ok].

Try it here. Expects input like "HELLO""world""!!!!!" (so no commas).

Explanation

$o     Read in whole input as characters
d      Duplicate top of stack (the ")
0Z     Count how often this appears in the stack
2:     Divide by two
$z     Store this in the register (z)
Iz:    Length of stack divided by z (k)
$x     Dump one element from the front/bottom of stack
d      Duplicate top of stack (which is k)
0G     Insert it at the front/bottom of stack
2-     k-2

  [                              Open for loop that repeats k-2 times
   i1+                           Loop counter + 1 (i)
      z[                         Open for loop that repeats z times
        d                        Duplicate top of stack (which is i)
         i                       Loop counter (j)
          0c                     Copy k from front of stack
            *                    Multiply (j*k)
             +                   Add (j*k + i)
              c                  Copy character at position j*k+i to the top
               $r                Swap top two elements of stack (so i is on top)
                 ]               Close for loop
                  x              Dump the top of stack (dump i)
                   z$(           Start a new loop with the top z elements
                      s          Sort
                       r$O       Reverse and output the whole (loop) stack as characters
                          k      Break - exits while loop
                           ].    Close for loop and stop
share|improve this answer

Japt, 12 bytes 20

Ny m_q n q)q

Doesn't work in the online interpreter as the transpose function is messed up. Hopefully that doesn't make this invalid

Explanation

Ny       // Transposes inputs.
  m_     // Maps through each new string
    q    // Split string
    n    // Sort string
    q    // Join
)q       // Join again
share|improve this answer

GolfScript, 8 bytes

~zip{$}%

Try it online on Web GolfScript.

How it works

~         # Evaluate the input.
 zip      # Zip it.
    {$}%  # Map sort ($) over the resulting array.
share|improve this answer

𝔼𝕊𝕄𝕚𝕟, 19 chars / 39 bytes

Ѩťᶏש,ï)ć⇀⟦$]ú⬮ø⬯)ø⬯

Try it here (Firefox only).

share|improve this answer

K, 10 bytes

,/{x@<x}'+

Join (,/) the sort of ({x@<x}) each (') of the transpose (+) of a list of strings.

In action:

  ,/{x@<x}'+("HELLO";"world";"!!!!!")
"!Hw!Eo!Lr!Ll!Od"

Simple, but K is hurt a bit here by not having a single-character sort function and instead dividing the operation into a scatter-gather index operator @ and a primitive which yields the permutation vector which would sort a list <.

share|improve this answer

C++14, 152 bytes

#include<iostream>
#include<regex>
[](auto s){for(int i=0;i<s[0].size();++i){auto r=""s;for(auto k:s)r+=k[i];std::sort(begin(r),end(r));std::cout<<r;}};

Not using any advantage of map+zip (guess why)

Ungolfed + usage

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>

int main()
{
    auto lambda = [](auto s)
    {
        for (int i = 0; i < s[0].size(); ++i)
        {
            auto r = ""s;
            for (auto k : s)
                r += k[i];
            std::sort(begin(r), end(r));
            std::cout << r;
        }
    };

    std::vector<std::string> data = { "HELLO", "world", "!!!!!" };
    lambda(data);
}
share|improve this answer

Mathematica, 51 bytes

""<>SortBy@ToCharacterCode/@Transpose@Characters@#&

String manipulation in Mathematica is expensive...

share|improve this answer

Clojure/ClojureScript, 43 bytes

#(apply str(mapcat sort(apply map list %)))

Creates an anonymous function. Written in a ClojueScript REPL, should also be valid Clojure.

Enter it here, then call via (*1 ["HELLO" "world" "!!!!!"]). Or do (def f *1) and then use (f ["abc" "cba"]).

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.