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 code-golf, 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>
34 Answers 34
GS2, 4 bytes
*Ü■しかく/
This reads the strings from STDIN, separated by linefeeds.
The source code uses the CP437 encoding. Try it online!
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.
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
).
-
\$\begingroup\$ i came up with exactly this! \$\endgroup\$proud haskeller– proud haskeller2015年11月23日 17:58:57 +00:00Commented Nov 23, 2015 at 17:58
-
\$\begingroup\$ I did not; I keep forgetting to exploit the Monad instance for things like lists. (+1) \$\endgroup\$ballesta25– ballesta252015年11月24日 10:42:30 +00:00Commented Nov 24, 2015 at 10:42
JavaScript (ES6), 57 bytes
a=>a[0].replace(/./g,(c,i)=>a.map(w=>w[i]).sort().join``)
TeaScript, 9 bytes
_t¡ßlp¡)μ
TeaScript has all the right built-ins implemented in all the wrong ways.
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
-
\$\begingroup\$ @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 \$\endgroup\$Downgoat– Downgoat2015年11月23日 02:11:08 +00:00Commented Nov 23, 2015 at 2:11
-
1\$\begingroup\$ I beat you by like 14 seconds ;P. \$\endgroup\$Maltysen– Maltysen2015年11月23日 00:25:56 +00:00Commented Nov 23, 2015 at 0:25
Python, (削除) 50 (削除ここまで) 48 bytes
lambda x,y=''.join:y(map(y,map(sorted,zip(*x))))
Thanks to @xnor for -2 bytes!
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
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 <
.
Stax, 5 bytes
LMFop
So close to LMNOP :(
Run and debug it at staxlang.xyz!
Put all inputs into one list of strings (L
), and transpose this list (M
). For each resulting string (F
), sort (o
) and print (p
) it.
R, 56 bytes
\(a,`^`=Reduce)paste0^apply(rbind^strsplit(a,""),2,sort)
It seems that to get the shortest solution one should avoid those quite verbose calculations of the length: be it nchar()
or length()
.
Here is a function that inputs a vector of strings and outputs a concatenated string with the sorted characters.
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
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);
}
Mathematica, 51 bytes
""<>SortBy@ToCharacterCode/@Transpose@Characters@#&
String manipulation in Mathematica is expensive...
Japt, 12 bytes (削除) 20 (削除ここまで)
Ny m_q n q)q
Explanation
Ny // Transpose inputs
m_ // Maps through each new string
q // Split string
n // Sort string
q // Join
)q // Join again
Perl 6, 33 bytes
{[~] flat ([Z] @_».comb)».sort}
Example usage:
say {[~] flat ([Z] @_».comb)».sort}(< abc cba >) # acbbca
my &code = my $code = {[~] flat ([Z] @_».comb)».sort}
say code "HELLO","world","!!!!!"; # !Hw!Eo!Lr!Ll!Od
say ((<cba abc>),(<testing gnitset gttseni>)).map($code);
# (acbbac ggtentiststteisenngit)
ESMin, 15 chars / 30 bytes
Ѩťaï)ć⇀ѨŌ$ø⬯)ø⬯
Just realized that Lodash's sortBy function works on strings, too.
Jelly, 3 bytes
ZṢ€
Only valid if considered as a full program: the resulting value is a list of strings, but when it's printed Jelly implicitly flattens it.
€ Map
Ṣ sort
Z over the columns of the input.
PHP, (削除) 92 (削除ここまで) 91 bytes
for($argv[0]='';$a=array_column(array_map(str_split,$argv),$i++|0);print join($a))sort($a);
I'm confident this could be done shorter by not trying to use PHP's built-in array functions, but had to try!
Or 85 bytes
@Night2's swing, done shorter by not trying to use PHP's built-in array functions:
for(;''<$argv[1][$i++];print join($a))for($a=[];''<$a[]=$argv[++$$i][$i-1];sort($a));
-
\$\begingroup\$ @Night2 nicely done! You should post that one as your own. It's too bad that
array_column
won't work on an array of strings otherwise it'd be quite a bit more useful for CG. And of course having to skip$argv[0]
is always a pain too... \$\endgroup\$640KB– 640KB2019年08月22日 13:25:35 +00:00Commented Aug 22, 2019 at 13:25
PowerShell Core, (削除) 56 (削除ここまで) 50 bytes
-join(($a=$args)[0]|% t*y|%{$a|% c*rs($i++)|sort})
-6 bytes thanks to mazzy
-
1\$\begingroup\$ ? Try it online! \$\endgroup\$mazzy– mazzy2020年10月30日 10:55:49 +00:00Commented Oct 30, 2020 at 10:55
Brev, (削除) 53 (削除ここまで) 41 bytes
(as-list flatten(over(sort args char<?)))
Example:
((as-list flatten (over (sort args char<?))) "HELLO" "world" "!!!!!")
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