32
\$\begingroup\$

If you sort a string you'll typically get something like:

         ':Iaaceeefggghiiiiklllllmnnooooprrssstttttuuyyyy

Yes, that was the first sentence sorted.

As you can see, there are a lot of repeated characters, aa, eee, ttttt, 9 spaces and so on.

If we add 128 to the ASCII-value of the first duplicate, 256 to the second, 384 to the third and so on, sort it again and output the new string (modulus 128 to get the same characters back) we get the string:

 ':Iacefghiklmnoprstuy aegilnorstuy egilosty iloty lt    

(Note the single leading space and the 4 trailing spaces).

The string is "sequentially sorted" <space>':I....uy, <space>aeg....uy, <space>egi....ty, <space>iloty, <space>lt, <space>, <space>,<space>, <space>.

It might be easier to visualize this if we use a string with digits in it. The string 111222334 will when "sorted" be: 123412312.

Challenge:

To no surprise, the challenge is to write a code that sorts a string according to the description above.

You can assume that the input string will contain only printable ASCII-characters in the range 32-126 (space to tilde).


Test cases:

**Test cases:**
 *:Tacest*es*s*

If you sort a string you'll typically get something like:
 ':Iacefghiklmnoprstuy aegilnorstuy egilosty iloty lt    

Hello, World!
 !,HWdelorlol

#MATLAB, 114 bytes
 #,14ABLMTbesty 1A

f=@(s)[mod(sort(cell2mat(cellfun(@(c)c+128*(0:nnz(c)-1),mat2cell(sort(s),1,histc(s,unique(s))),'un',0))),128),''];
'()*+,-0128:;=@[]acdefhilmnoqrstuz'(),0128@acefilmnorstu'(),12celmnostu'(),12celnstu(),clnst(),cls(),cs(),()()()()

This is , so the shortest code in each language counted in bytes will winref.

\$\endgroup\$
9
  • \$\begingroup\$ Title is a bit confusing, resulting in me thinking this and ignoring the description: tio.run/nexus/05ab1e#@1@td2jh4ZVe//… Nice challenge otherwise, I'll work on expanding that to meet the brief. \$\endgroup\$ Jan 10, 2017 at 21:40
  • \$\begingroup\$ Can we output a list of characters instead of a string? \$\endgroup\$
    – Wheat Wizard
    Jan 10, 2017 at 21:52
  • 1
    \$\begingroup\$ Proposed alternate title: ,Safginorst orst ort :P \$\endgroup\$
    – DJMcMayhem
    Jan 12, 2017 at 18:03
  • 1
    \$\begingroup\$ @DJMcMayhem haha, nice and descriptive title... It's actually possible to pronounce, so it could work :) \$\endgroup\$ Jan 12, 2017 at 22:21
  • 1
    \$\begingroup\$ It would be funny if someone made an answer that was already sorted |:) \$\endgroup\$
    – ckjbgames
    Feb 3, 2017 at 18:34

30 Answers 30

16
\$\begingroup\$

Pyth, 5 bytes

s.T.g

Test suite

Very straightforward: Group and sort, transpose, concatenate.

s.T.g
s.T.gkQ    Implicit variables
   .gkQ    Group the input input lists of elements whose values match when the
           identity function is applied, sorted by the output value.
 .T        Transpose, skipping empty values. This puts all first characters into
           a list, then all second, etc.
s          Concatenate.
\$\endgroup\$
2
  • \$\begingroup\$ Pyth has everything to become new J, it's awesome \$\endgroup\$
    – shabunc
    Jan 12, 2017 at 1:36
  • 4
    \$\begingroup\$ @shabunc If you want to see the new J, check out github.com/DennisMitchell/jelly \$\endgroup\$
    – isaacg
    Jan 12, 2017 at 4:51
15
\$\begingroup\$

Jelly, 3 bytes

ĠZị

Try it online!

How it works

Oh boy, this challenge was all but made for Jelly.

The group atom (Ġ) takes an array1 as input and groups indices that correspond to identical elements of the array. The array of index groups is sorted with the corresponding elements as keys, which is precisely the order we require for this challenge.

Next, the zip atom (Z) transposes rows and columns of the generated (ragged) matrix of indices. This simply consists of reading the columns of the matrix, skipping elements that are not present in that column. As a result, we get the first index of the character with the lowest code point, followed by the first index of the character with the second lowest code point, … followed by the second index of the character with the lowest code point, etc.

Finally, the unindex atom () retrieves the elements of the input array at all of its indices in the generated order. The result is a 2D character array, which Jelly flattens before printing it.


1 Jelly doesn't have a string type, just arrays of characters.

\$\endgroup\$
2
  • \$\begingroup\$ "Oh boy, this challenge was all but made for Jelly." -> 3 byte answer \$\endgroup\$ Jan 12, 2017 at 11:29
  • \$\begingroup\$ As I said, almost made for Jelly. :) \$\endgroup\$
    – Dennis
    Jan 12, 2017 at 12:54
10
\$\begingroup\$

Python 3, 109 105 104 103 99 93 90 88 81 79 69 bytes

2 bytes saved thanks to FlipTack

7 bytes saved because flornquake caught my dumb error

2 bytes saved thanks to xnor

10 bytes saved thanks to Dennis

a=[*input()]
while a:
    for c in sorted({*a}):print(end=c);a.remove(c)

Explanation

We start by converting our string to a list using a splat and storing that list in a variable a. Then while our a is not the empty list we go through each unique member of a in sorted order, print it and remove a copy of that character from the list.

Each iteration prints thus prints one copy of each character present in a.

\$\endgroup\$
10
  • 1
    \$\begingroup\$ @StewieGriffin set is an unsorted set. \$\endgroup\$
    – FlipTack
    Jan 10, 2017 at 22:03
  • 2
    \$\begingroup\$ @StewieGriffin when printed they are sorted but not by their ASCII values exactly. It often appears they are but I believe they are sorted by some type of hash. \$\endgroup\$
    – Wheat Wizard
    Jan 10, 2017 at 22:05
  • 1
    \$\begingroup\$ You can make f a string instead of a list to save a few bytes. \$\endgroup\$
    – flornquake
    Jan 11, 2017 at 3:08
  • 1
    \$\begingroup\$ If you take a=list(input()), you can do a.remove(c), which is a net savings. \$\endgroup\$
    – xnor
    Jan 11, 2017 at 3:43
  • 1
    \$\begingroup\$ Switching to Python 3 would save a lot of bytes. tio.run/nexus/… \$\endgroup\$
    – Dennis
    Jan 11, 2017 at 4:12
7
\$\begingroup\$

Haskell, 44 bytes

import Data.List
concat.transpose.group.sort

Usage example:

Prelude Data.List> concat.transpose.group.sort $ "If you sort a string you'll typically get something like:"
" ':Iacefghiklmnoprstuy aegilnorstuy egilosty iloty lt    "

Sort, group equal chars to a list of strings (e.g. "aabbc" -> ["aa","bb","c"]), transpose and flatten into a single string, again.

\$\endgroup\$
1
  • \$\begingroup\$ This might be stupid thing to ask but how does this adds 128,256,384.... to the repeated values? \$\endgroup\$ Jan 19, 2022 at 5:44
6
\$\begingroup\$

Python 2, 75 bytes

lambda s:`zip(*sorted((s[:i].count(c),c)for i,c in enumerate(s)))[1]`[2::5]

Try it online!

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Don't know if it's valid but lambda s:`[sorted((1e9+s[:i].count(c),c)for i,c in enumerate(s))]`[18::21] works for strings with max length 9e9. \$\endgroup\$
    – xnor
    Jan 11, 2017 at 4:22
  • \$\begingroup\$ @xnor you can drop the [] and change 18 to 17 to save two bytes. lambda s:`sorted((1e9+s[:i].count(c),c)for i,c in enumerate(s))`[17::21] \$\endgroup\$
    – Wheat Wizard
    Jan 11, 2017 at 4:38
  • \$\begingroup\$ @xnor At the very least, this should be a valid 32-bit Python golf. I tried to get rid off the zip, but I don't think adding 1e9 would have ever occurred to me... Thanks! \$\endgroup\$
    – Dennis
    Jan 11, 2017 at 4:45
  • \$\begingroup\$ @WheatWizard Good eye. Thanks! \$\endgroup\$
    – Dennis
    Jan 11, 2017 at 4:45
  • \$\begingroup\$ This fails if the string has backslashes in it. \$\endgroup\$
    – Lynn
    Jan 12, 2017 at 3:02
5
\$\begingroup\$

APL (Dyalog Unicode), 21 20 bytes

t[0~⍨∊⍉(⊂⍋∪t)⌷⊢⌸t←⍞]

Try it online!

t[...] index t (to be defined shortly) with...

0~⍨ zeros removed from

 the enlisted (flattened)

 transposed

(⊂)⌷ reordered using…

   the indices which would sort

   the unique letters of

  tt (to be defined shortly)

⊢⌸t keyed* t, which has the value of

   prompted text input

TryAPL online!


⊢⌸t creates a table where the rows (padded with zeros for a rectangular table) list each unique letters' indices in t.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ which of the glyphs are more expensive? \$\endgroup\$
    – ren
    Jan 11, 2017 at 6:39
  • \$\begingroup\$ @ren Updated to use new technology that allows counting each glyph as a single byte. \$\endgroup\$
    – Adám
    Jan 19, 2022 at 8:43
4
\$\begingroup\$

C, 109 106 105 104 102 100 97 98 96 91 Bytes

Back up to 98 Bytes, needed to initialize j to make f(n) re-useable

Down to 96 Bytes using puts in place of strlen B-)

It's strange I had to back to strlen but I got rid of the for(;i++;) loop so now it's down to 91 Bytes. Apparently the man page for puts reads;

"RETURNS
   If successful, the result is a nonnegative integer; otherwise, the result is `EOF'."

... I was lucky it was working in the first place

char*c,i,j;f(m){for(j=strlen(m);j;++i)for(c=m;*c;c++)if(*c==i){*c=7,putchar(i),j--;break;}}

test code...

main(c,v)char**v;
{
    char test[] = "If you sort a string you'll typically get something like: ";
    char test2[] = "Hello, World!";

    f(test);puts("");    
    f(test2);puts("");    
}

Here are a few test cases, now it's time to golf this down

C:\eng\golf>a.exe
 ':Iacefghiklmnoprstuy aegilnorstuy egilosty iloty lt
 !,HWdelorlo
\$\endgroup\$
2
  • \$\begingroup\$ Are the trailing spaces left out in the first test case? \$\endgroup\$ Jan 10, 2017 at 22:07
  • \$\begingroup\$ I have three trailing spaces in the first test case... That's because I didn't include the trailing space on the input string ;-) \$\endgroup\$
    – cleblanc
    Jan 10, 2017 at 22:10
4
\$\begingroup\$

Mathematica, 68 60 59 bytes

Split[Characters@#~SortBy~ToCharacterCode]~Flatten~{2}<>""&

Accepts a String. Outputs a String.

If list of characters were allowed (46 bytes):

Split[#~SortBy~ToCharacterCode]~Flatten~{2,1}&

Version using Sort (40 bytes):

Split@Sort@Characters@#~Flatten~{2}<>""&

This version cannot be my answer because Sort cannot be used here; Sort sorts by canonical order, not by character code.

\$\endgroup\$
7
  • \$\begingroup\$ I don't know mathematica so this might be just fine, but did you read this comment? \$\endgroup\$ Jan 10, 2017 at 23:22
  • \$\begingroup\$ @StewieGriffin Welp, nope. I can fix that, but doesn't that give an unfair advantage to languages that don't have a String vs Char[] distinction? Related meta discussion \$\endgroup\$ Jan 10, 2017 at 23:29
  • \$\begingroup\$ Good point. I made a correction, see the comment below the original. Fair? I'm not sure if this makes your answer valid or not. \$\endgroup\$ Jan 10, 2017 at 23:42
  • \$\begingroup\$ @StewieGriffin Mathematica doesn't have a distinction between characters and strings. Even the Characters command technically output a list of length-1 strings. \$\endgroup\$ Jan 10, 2017 at 23:58
  • 1
    \$\begingroup\$ @StewieGriffin I think this is also relevant. I think it's better to allow the input in any reasonable format, be it a string, list of length 1 strings, array of characters, array of bytes, etc. \$\endgroup\$
    – user61980
    Jan 11, 2017 at 1:47
3
\$\begingroup\$

Python 2, 77 76 bytes

d={}
def f(c):d[c]=r=d.get(c,c),;return r
print`sorted(input(),key=f)`[2::5]

Takes a quoted string as input from stdin.

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ I think this isn't allowed because functions have to be re-usable. You could make it a program. \$\endgroup\$
    – xnor
    Jan 11, 2017 at 3:33
  • \$\begingroup\$ I really like this method, sorting with a function that mutates. The nesting of tuples is clever too. \$\endgroup\$
    – xnor
    Jan 11, 2017 at 4:10
  • \$\begingroup\$ @xnor Thanks, fixed. \$\endgroup\$
    – flornquake
    Jan 11, 2017 at 9:20
3
\$\begingroup\$

JavaScript (ES6), 79 bytes

f=s=>s&&(a=[...new Set(s)]).sort().join``+f(a.reduce((s,e)=>s.replace(e,``),s))
<input oninput=o.textContent=f(this.value)><pre id=o>

Works by extracting the set of unique characters, sorting it, removing them from the original string, and recursively calculating the sort of the rest of the string. 81 byte solution that I found interesting:

f=s=>s&&(s=[...s].sort().join``).replace(r=/(.)(\1*)/g,"$1")+f(s.replace(r,"$2"))
\$\endgroup\$
3
\$\begingroup\$

J, 16 15 bytes

/:+/@(={:)\;"0]

This is a verb that takes and returns one string. Try it online!

Miles saved a byte, thanks!

Explanation

Nothing too fancy here: sort primarily by order of occurrence, secondarily by char value.

/:+/@(={:)\;"0]  Input is y.
          \      Map over prefixes:
  +/              Sum
    @(   )        of
      =           bit-array of equality
       {:         with last element.
                 This gives an array of integers whose i'th element is k
                 if index i is the k'th occurrence of y[i].
           ;     Pair this array
            "0   element-wise
              ]  with y
/:               and sort y using it as key.
\$\endgroup\$
2
  • \$\begingroup\$ I think you can save a byte moving summation to the outside of the parentheses `+/@(={:)` \$\endgroup\$
    – miles
    Jan 12, 2017 at 9:15
  • \$\begingroup\$ @Miles Oh yeah, because a train has infinite rank. Nice, thanks! \$\endgroup\$
    – Zgarb
    Jan 12, 2017 at 9:19
2
\$\begingroup\$

Brainf*ck, 458 226 bytes

,[>>>>>>,]<<<<<<[[-<<<+<<<]>>>[>>>[>>>>>>]<<<[>>--[<->--]<-<[>->+<[>]>[<+>-]<<[<]>-]>>.[[-]<]<<<[[>>>>>>+<<<<<<-]<<<]>>>>>>]>>>[>>>[>>>>>>]<<<[>>--[<->--]<-<[>->+<[>]>[<+>-]<<[<]>-]>>[-<+<+>>]<[->>+<<]<[<<<<<<]>>>]>>>]]<<<<<<]

Try it online! - BF

Numberwang, 262 226 bytes

8400000087111111442111911170004000400000071114002241202271214020914070419027114170270034427171114400000091111112711170000007000400040000007111400224120227121402091407041902711417027004219190071420091171411111170007000771111117

Try it online! - NW

I put both of these here because they are identical code.

\$\endgroup\$
0
2
\$\begingroup\$

PHP, 83 bytes

for($s=count_chars($argv[1]);$s=array_filter($s);$c%=128)echo$s[++$c]--?chr($c):'';

Unfortunately you can't have unset in a ternary so I need to use the annoyingly long array_filter.
Use like:

php -r "for($s=count_chars($argv[1]);$s=array_filter($s);$c%=128)echo$s[++$c]--?chr($c):'';" "If you sort a string you'll typically get something like:"
\$\endgroup\$
2
\$\begingroup\$

Python 2, 70 bytes

f=lambda s,i=0,c='':s[i>>7:]and(s.count(c)>i>>7)*c+f(s,i+1,chr(i%128))

Try it online

This is very inefficient. The test link changes the i>>7 to i>>5 and sets the recursion limit to 10000. Assumes the inputs only has ASCII values up to 126.

Uses the div-mod trick to iterate through two loops: minimum counts i/128 in the outer loop and ASCII values i%128 in the inner loop. Includes a character c with the given ASCII value if the number of times it appears in the string is at least its minimum count.

The code uses a trick to simulate the assignment c=chr(i%128) so that it can be referenced in the expression (s.count(c)>i>>7)*c. Python lambdas do not allow assignment because they only take expressions. Converting to a def or full program is still a net loss here.

Instead, the function pushes forward the value chr(i%128) to the next recursive call as an optional input. This is off by one because i has been incremented, but doesn't matter as long as the string doesn't contain special character '\x7f' (we could also raise 128 to 256). The initial c='' is harmless.

\$\endgroup\$
2
\$\begingroup\$

V, 37 36 bytes

Thanks @DJMcMayhem for the byte!

Í./&ò
dd:sor
Íî
òͨ.©¨±«©±À!¨.«©/±³²

Try it online!

Not sure I like the regex at the end, but I needed to make the ò break somehow.

Explain

Í./&ò                    #All chars on their own line
dd:sor                   #Delete empty line, sort chars
Íî                       #Join all lines together s/\n//
òͨ.©¨±«©±À!¨.«©/±³² #until breaking s/\v(.)(\1+)\1@!(.+)/\3\2\1
\$\endgroup\$
1
  • \$\begingroup\$ Íî (or :%s/\n//g) is shorter than VGgJ \$\endgroup\$
    – DJMcMayhem
    Jan 12, 2017 at 15:40
2
\$\begingroup\$

Vyxal d, 3 bytes

sĠ∩

Try it Online!

s   # Sort
 Ġ  # Group run lengths
  ∩ # Transpose
    # (d flag) take deep sum
\$\endgroup\$
1
\$\begingroup\$

Perl 6, 68 bytes

{my \a=.comb.sort;[~] flat roundrobin |a.squish.map({grep *eq$_,a})}

I was a little surprised to find that there's no built-in way to group like elements in a list. That's what the squish-map bit does.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ I get "This Seq has already been iterated" unless I rename a to @a (+2 bytes). Also, grep *eq$_, can be written grep $_, (-3 bytes) since a string is a valid smart-matcher. \$\endgroup\$
    – smls
    Jan 11, 2017 at 14:25
  • 1
    \$\begingroup\$ {[~] flat roundrobin |.comb.classify(~*){*}.sort»[*]} -- This variation is only 54 bytes. \$\endgroup\$
    – smls
    Jan 11, 2017 at 14:45
  • \$\begingroup\$ @smis I don't see that error. Maybe we're using different versions? I'm on rakudo-star-2016.10. Anyway, your solution puts mine to shame, you should post it as a separate answer. \$\endgroup\$
    – Sean
    Jan 11, 2017 at 17:33
  • \$\begingroup\$ I'm using a bleeding-edge Rakudo compiled from the main branch of the git repo this week. Anyway, I posted the classify-based solution as a separate answer now. \$\endgroup\$
    – smls
    Jan 11, 2017 at 18:43
1
\$\begingroup\$

JavaScript (ES6), 77 75 bytes

s=>(a=[],x={},[...s].sort().map(c=>a[x[c]=n=-~x[c]]=(a[n]||'')+c),a).join``

Stable sorts the lexicographically sorted string by nth occurence

F=s=>(a=[],x={},[...s].sort().map(c=>a[x[c]=n=-~x[c]]=(a[n]||'')+c),a).join``

const update = () => {
  console.clear();
  console.log(F(input.value));
};
input.oninput = update;
update();
#input {
  width: 100%;
  box-sizing: border-box;
}
<input id="input" type="text" value="         ':Iaaceeefggghiiiiklllllmnnooooprrssstttttuuyyyy" length=99/>
<div id="output"></div>

\$\endgroup\$
2
  • \$\begingroup\$ 1+~~ is the same as -~. \$\endgroup\$
    – Neil
    Jan 11, 2017 at 9:34
  • \$\begingroup\$ @Neil Awesome thanks -2 bytes \$\endgroup\$ Jan 11, 2017 at 11:49
1
\$\begingroup\$

Perl 6, 54 bytes

{[~] flat roundrobin |.comb.classify(~*){*}.sort»[*]}

Explanation:

  • { }: A lambda that takes one argument -- e.g. 21211.
  • .comb: Split the input argument into a list of characters -- e.g. (2,1,2,1,1).
  • .classify(~*): Group the characters using string comparison as the grouping condition, returning an unordered Hash -- e.g. { 2=>[2,2], 1=>[1,1,1] }.
  • {*}: Return a list of all values of the Hash -- e.g. [2,2], [1,1,1].
  • .sort: Sort it -- e.g. [1,1,1], [2,2].
  • »[*]: Strip the item containers the arrays were wrapped in due to being in the hash, so that they won't be considered as a single item in the following step -- e.g. (1,1,1), (2,2).
  • roundrobin |: Zip the sub-lists until all are exhausted -- e.g. (1,2), (1,2), (1).
  • flat: Flatten the result -- e.g. 1, 2, 1, 2, 1.
  • [~]: Concatenate it to get a string again -- e.g. 12121.

(Credit for the roundrobin approach goes to Sean's answer.)

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 15 bytes

{.¡"ä"©¹g׫øJ®K

Try it online! or as a Test suite

Explanation

{                # sort input
 .¡              # group by equal elements
   "ä"©          # push "ä" and store a copy in the register
       ¹g×       # repeat the "ä" input-nr times
          «      # concatenate the result to each string in the grouped input
           ø     # zip
            J    # join to string
             ®K  # remove all instances of "ä" in the string

10 of the 15 bytes are for getting around 05AB1E's way of handling zipping strings of different length.

\$\endgroup\$
1
\$\begingroup\$

FSharp, 194 190 170 140 133 bytes

let f=Seq.map
let(@)=(>>)
f [email protected] id@f([email protected]((*)128@(+)))@[email protected]@f((%)@(|>)128@byte)@Array.ofSeq@f char

Using Seq instead of Array saves a couple of bytes

Defining a shorter name, and using another maps to avoid a (fun ->) block

It turns out F# can map a char to an in, so removing the shortened name of System.Text.Encoding.ASCII, and adding in another map saves me 20 bytes!

Returning a char array instead of a string, saves me 30 bytes!

I no longer need to make sure it's a string, saves me 7 bytes

\$\endgroup\$
1
\$\begingroup\$

Husk, 4 bytes

ΣTgO

Try it online!

Explanation

ΣTgO
   O Order
  g  group
 T   Transpose
Σ    join
\$\endgroup\$
1
\$\begingroup\$

JavaScript (Node.js), 71 bytes

f=x=>x&&[...x].filter(k=c=>k[c]?![h+=c]:k[c]=1,h='').sort().join``+f(h)

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Japt -P, 4 bytes

Input as a character array, output as a string.

ü Õc

Try it

ü Õc     :Implicit input of character array
ü        :Group & sort
  Õ      :Transpose
   c     :Flatten
         :Implicitly join & output
\$\endgroup\$
0
\$\begingroup\$

JavaScript (ES6), 114 bytes

Separated with newline for clarity, not part of byte count:

s=>[...s].map(a=>(m[a]=-~m[a])*128+a.charCodeAt(),m={})
.sort((a,b)=>a-b).map(a=>String.fromCharCode(a%128)).join``

Demo

`**Test cases:**
 *:Tacest*es*s*

If you sort a string you'll typically get something like:
 ':Iacefghiklmnoprstuy aegilnorstuy egilosty iloty lt    

Hello, World!
 !,HWdelorlol

#MATLAB, 114 bytes
 #,14ABLMTbesty 1A

f=@(s)[mod(sort(cell2mat(cellfun(@(c)c+128*(0:nnz(c)-1),mat2cell(sort(s),1,histc(s,unique(s))),'un',0))),128),''];
'()*+,-0128:;=@[]acdefhilmnoqrstuz'(),0128@acefilmnorstu'(),12celmnostu'(),12celnstu(),clnst(),cls(),cs(),()()()()`.split`\n\n`.map(s=>(p=s.split`\n`,console.log(`${p[0]}\n\n${r=f(p[0])}\n\nmatch: ${r==p[1]}`)),
f=s=>[...s].map(a=>(m[a]=-~m[a])*128+a.charCodeAt(),m={}).sort((a,b)=>a-b).map(a=>String.fromCharCode(a%128)).join``)

\$\endgroup\$
1
  • \$\begingroup\$ The same bytecount as my Matlab code, and the exact same approach. Haven't attempted to golf mine yet though. I'll probably upvote later if you add an explanation :-) (I've made a principle out of not upvoting answers without explanations, even when I understand it) :-) \$\endgroup\$ Jan 10, 2017 at 23:51
0
\$\begingroup\$

Clojure, 79 bytes

#(for[V[(group-by(fn[s]s)%)]i(range 1e9)k(sort(keys V))c[(get(V k)i)]:when c]c)

An anonymous function, returns a sequence of characters. Supports up-to 10^9 repetitions of any characters, which should be plenty.

\$\endgroup\$
0
\$\begingroup\$

Retina, 24 bytes

O`.
O$#`(.)(?=(\1)*)
$#2

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Ruby, 59+1 = 60 bytes

Adds one byte for the -n flag. Port of @PatrickRoberts' dictionary solution.

d={};print *$_.chars.sort_by{|c|d[c]||=0;c.ord+128*d[c]+=1}
\$\endgroup\$
0
\$\begingroup\$

BQN, 6 bytesSBCS

∾·⊒⊸⊔∧

Run online!

sort, group by occurrence count, join.

\$\endgroup\$
0
\$\begingroup\$

Factor + grouping.extras, 48 bytes

[ natural-sort [ ] group-by values round-robin ]

Attempt This Online!

  • natural-sort Sort the input
  • [ ] group-by values Group like contiguous elements, e.g. "aabbc" -> { "aa" "bb" "c" }
  • round-robin One from each group in order, until there are no elements left. e.g. { "aa" "bb" "c" } -> "abcab"
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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