Trier une chaîne, sorte de

29

Si vous triez une chaîne, vous obtiendrez généralement quelque chose comme:

         ':Iaaceeefggghiiiiklllllmnnooooprrssstttttuuyyyy

Oui, c'était la première phrase triée.

Comme vous pouvez le voir, il y a beaucoup de caractères répétés, aa, eee,ttttt , 9 places et ainsi de suite.

Si nous ajoutons 128à la valeur ASCII du premier doublon, 256au second, 384au troisième et ainsi de suite, trions-le à nouveau et sortons la nouvelle chaîne (module 128 pour récupérer les mêmes caractères), nous obtenons la chaîne:

 ':Iacefghiklmnoprstuy aegilnorstuy egilosty iloty lt    

(Notez le seul espace de tête et les 4 espaces de fin).

La chaîne est "ordonnée de manière séquentielle" <space>':I....uy, <space>aeg....uy, <space>egi....ty, <space>iloty, <space>lt, <space>, <space>, <space>, <space>.

Il pourrait être plus facile de visualiser cela si nous utilisons une chaîne contenant des chiffres. La chaîne 111222334sera quand « triée » être: 123412312.

Défi:

Sans surprise, le défi est d'écrire un code qui trie une chaîne selon la description ci-dessus.

Vous pouvez supposer que la chaîne d'entrée ne contiendra que des caractères ASCII imprimables compris entre 32 et 126 (espace au tilde).


Cas de test:

**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(),()()()()

Il s'agit de , donc le code le plus court dans chaque langue compté en octets gagnera ref .

Stewie Griffin
la source
Le titre est un peu déroutant, ce qui me fait penser à cela et ignorer la description: tio.run/nexus/05ab1e#@1@td2jh4ZVe//… Beau défi sinon, je vais travailler sur l'élargissement pour répondre au brief.
Magic Octopus Urn
Pouvons-nous produire une liste de caractères au lieu d'une chaîne?
Wheat Wizard
Si vous pouvez saisir une chaîne, la sortie doit également être une chaîne. Si une liste de caractères est la manière normale d'entrer et de sortir des chaînes dans vos langues, alors c'est OK. Vous ne pouvez par exemple pas sortir {'S', 'g', 'i', 'n', 'r', 't'}en Python, car la façon "normale" de le faire est "String".
Stewie Griffin
Je vais corriger mon commentaire ci-dessus: une chaîne est une liste de caractères , donc une liste de caractères est acceptée en sortie. Cependant, une liste de chaînes n'est pas acceptée. Cela signifie que s'il est possible d'ajouter un deuxième caractère à un élément de votre liste, il n'est pas accepté. A titre d'exemple: {'a','b'}ne sont pas acceptés dans Matlab puisque vous pouvez ajouter un caractère à chacun des personnages comme celui - ci: {'aa','b'}. Vos entrées et sorties doivent être au même format.
Stewie Griffin
@StewieGriffin Lorsque vous dites trié selon la description ci-dessus. Voulez-vous dire que mon algorithme de tri doit suivre le processus de modification des valeurs ASCII ou qu'il doit simplement produire la même sortie que cet algorithme?
George Reith

Réponses:

15

Pyth, 5 octets

s.T.g

Suite de tests

Très simple: regrouper et trier, transposer, concaténer.

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.
isaacg
la source
Pyth a tout pour devenir un nouveau J, c'est génial
shabunc
3
@shabunc Si vous voulez voir le nouveau J, consultez github.com/DennisMitchell/jelly
isaacg
13

Gelée , 3 octets

ĠZị

Essayez-le en ligne!

Comment ça marche

Oh mon garçon, ce défi était tout sauf fait pour Jelly.

Le groupe atom ( Ġ) prend un tableau 1 en entrée et regroupe les indices qui correspondent à des éléments identiques du tableau. Le tableau des groupes d'index est trié avec les éléments correspondants sous forme de clés, ce qui est précisément l'ordre dont nous avons besoin pour ce défi.

Ensuite, l' atome zip (Z ) transpose les lignes et les colonnes de la matrice d'indices générée (irrégulière). Cela consiste simplement à lire les colonnes de la matrice, en sautant les éléments qui ne sont pas présents dans cette colonne. En conséquence, nous obtenons le premier index du caractère avec le point de code le plus bas, suivi du premier index du caractère avec le deuxième point de code le plus bas,… suivi du deuxième index du caractère avec le point de code le plus bas, etc.

Enfin, l' atome unindex ( ) récupère les éléments du tableau d'entrée à tous ses indices dans l'ordre généré. Le résultat est un tableau de caractères 2D que Jelly aplatit avant de l'imprimer.


1 Jelly n'a pas de type chaîne , juste des tableaux de caractères.

Dennis
la source
"Oh mon garçon, ce défi était tout sauf fait pour Jelly." -> réponse de 3 octets
geisterfurz007 Arrêtez ce chaos
Comme je l'ai dit, presque fait pour Jelly. :)
Dennis
10

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

2 octets économisés grâce à FlipTack

7 octets enregistrés parce que le tremblement de terre a attrapé mon erreur stupide

2 octets économisés grâce à xnor

10 octets économisés grâce à Dennis

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

Explication

Nous commençons par convertir notre chaîne en liste en utilisant un splat et en stockant cette liste dans une variable a. Ensuite, bien que notre aliste ne soit pas vide, nous parcourons chaque membre unique adans l'ordre trié, l'imprimons et supprimons une copie de ce caractère de la liste.

Chaque itération imprime ainsi une copie de chaque caractère présent dans a.

Assistant de blé
la source
1
@StewieGriffin setest un ensemble non trié.
FlipTack
2
@StewieGriffin une fois imprimés, ils sont triés mais pas selon leurs valeurs ASCII exactement. Il semble souvent qu'ils le sont, mais je crois qu'ils sont triés par un type de hachage.
Wheat Wizard
1
Vous pouvez créer fune chaîne au lieu d'une liste pour enregistrer quelques octets.
flornquake
1
Si vous prenez a=list(input()), vous pouvez le faire a.remove(c), ce qui représente une économie nette.
xnor
1
Passer à Python 3 économiserait beaucoup d'octets. tio.run/nexus/…
Dennis
6

Haskell, 44 octets

import Data.List
concat.transpose.group.sort

Exemple d'utilisation:

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

Trier, regrouper des caractères égaux dans une liste de chaînes (par exemple "aabbc"-> ["aa","bb","c"]), transposer et aplatir à nouveau en une seule chaîne.

nimi
la source
6

Python 2 , 75 octets

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

Essayez-le en ligne!

Dennis
la source
1
Je ne sais pas si elle est valide mais lambda s:`[sorted((1e9+s[:i].count(c),c)for i,c in enumerate(s))]`[18::21]fonctionne pour les chaînes de longueur maximale 9e9.
xnor
@xnor vous pouvez laisser tomber le []changer 18pour 17sauver deux octets. lambda s:`sorted((1e9+s[:i].count(c),c)for i,c in enumerate(s))`[17::21]
Wheat Wizard
@xnor À tout le moins, ce devrait être un golf Python 32 bits valide. J'ai essayé de m'en débarrasser zip, mais je ne pense pas que cela 1e9m'aurait été venu à l'esprit ... Merci!
Dennis
@WheatWizard Bon œil. Merci!
Dennis
Cela échoue si la chaîne contient des barres obliques inverses.
Lynn
4

Dyalog APL , 21 caractères = 39 octets

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

t[... ] index t (à définir prochainement) avec ...

0~⍨ zéros supprimés de

 l'enrôlé (aplati)

 transposé

(⊢⌸t)[... indexé ;] * t , indexé par ligne par ...

   les indices qui trieraient

   les lettres uniques de

  t←t , qui a la valeur de

   saisie de texte avec invite

TryAPL en ligne!


⊢⌸tcrée un tableau où les lignes (complétées par des zéros pour un tableau rectangulaire) listent les indices de chaque lettre unique en t .

Adam
la source
1
quels glyphes sont plus chers?
Ren
1
@wptreanor fait que le tout est UTF-8 au lieu d'un octet par caractère.
Adám
4

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

Sauvegarde jusqu'à 98 octets, nécessaire pour initialiser j pour rendre f (n) réutilisable

Jusqu'à 96 octets en utilisant met à la place de strlen B-)

C'est étrange, j'ai dû revenir à strlen mais je me suis débarrassé de la boucle for (; i ++;) alors maintenant, c'est à 91 octets. Apparemment, la page de manuel pour met des lectures;

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

... j'ai eu de la chance que ça marche en premier lieu

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;}}

code de test ...

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("");    
}

Voici quelques cas de test, il est maintenant temps de jouer au golf

C:\eng\golf>a.exe
 ':Iacefghiklmnoprstuy aegilnorstuy egilosty iloty lt
 !,HWdelorlo
cleblanc
la source
Les espaces de fin sont-ils omis dans le premier cas de test?
Stewie Griffin
J'ai trois espaces de fin dans le premier cas de test ... C'est parce que je n'ai pas inclus l'espace de fin dans la chaîne d'entrée ;-)
cleblanc
4

Mathematica, 68 60 59 octets

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

Accepte une chaîne. Génère une chaîne.

Si la liste des caractères était autorisée (46 octets):

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

Version utilisant Sort(40 octets):

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

Cette version ne peut pas être ma réponse car Sortne peut pas être utilisée ici; Sorttrie par ordre canonique et non par code de caractère.

JungHwan Min
la source
Je ne connais pas mathématique donc cela pourrait être très bien, mais avez-vous lu ce commentaire?
Stewie Griffin
@StewieGriffin Welp, non. Je peux résoudre ce problème, mais cela ne donne-t-il pas un avantage injuste aux langues qui n'ont pas de distinction String vs Char []? Méta-discussion
connexe
Bon point. J'ai fait une correction, voir le commentaire ci-dessous l'original. Juste? Je ne sais pas si cela rend votre réponse valide ou non.
Stewie Griffin
@StewieGriffin Mathematica n'a pas de distinction entre les caractères et les chaînes. Même la Characterscommande affiche techniquement une liste de chaînes de longueur 1.
JungHwan Min
1
@StewieGriffin Je pense que cela est également pertinent . Je pense qu'il vaut mieux autoriser l'entrée dans n'importe quel format raisonnable, que ce soit une chaîne, une liste de chaînes de longueur 1, un tableau de caractères, un tableau d'octets, etc.
ngenisis
3

Python 2, 77 76 octets

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

Prend une chaîne entre guillemets en entrée de stdin.

Essayez-le en ligne!

tremblement de terre
la source
Je pense que ce n'est pas autorisé car les fonctions doivent être réutilisables . Vous pourriez en faire un programme.
xnor
J'aime vraiment cette méthode, le tri avec une fonction qui mute. L'emboîtement des tuples est intelligent aussi.
xnor
@xnor Merci, corrigé.
flornquake
3

JavaScript (ES6), 79 octets

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>

Fonctionne en extrayant le jeu de caractères uniques, en le triant, en les supprimant de la chaîne d'origine et en calculant récursivement le tri du reste de la chaîne. Solution de 81 octets que j'ai trouvée intéressante:

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

J , 16 15 octets

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

Il s'agit d'un verbe qui prend et renvoie une chaîne. Essayez-le en ligne!

Miles a sauvé un octet, merci!

Explication

Rien de trop sophistiqué ici: trier principalement par ordre d'occurrence, secondairement par valeur de caractère.

/:+/@(={:)\;"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.
Zgarb
la source
Je pense que vous pouvez enregistrer une sommation mobile d'octets à l'extérieur des parenthèses `+ / @ (= {:)`
miles
@Miles Oh oui, car un train a un rang infini. Bien, merci!
Zgarb
3

Mathematica, 55 octets, sans compétition

(Sort@Characters@#//.{a___,b_,b_,c___}:>{a,b,c,b})<>""&

Edit: Malheureusement, Mathematica sortn'est pas par codes de caractères, mais par ordre alphabétique, où les majuscules suivent immédiatement les minuscules (c'est Hi There-à- dire sont triées sur { , e, e, h, H, i, r, T}).

Cela fonctionne en utilisant des modèles:

//.{a___,b_,b_,c___}:>{a,b,c,b}
    a___       c___              (Three _) a zero or more members, named a and c
         b_,b_                   exactly one member, repeated twice (since they have the same name)
                    :>           Delayed Rule (replace left hand side with right hand side.)
                                 Delayed Rule evaluate on each substitution, avoiding conflicts with predefined variables
                      {a,b,c,b}  put one of the b-named member after all other sequences
//.                              repeat until no change (aka Replace Repeated)
espace
la source
1
Une chose mineure: Rule (->)devrait être RuleDelayed (:>)(pas de changement dans le nombre d'octets) car les deux côtés de Rulea des variables. Rulepeut provoquer des conflits avec les définitions préexistantes. Par exemple: a=3;5/.{a_->a}renvoie 3, non 5. ( a_->aévalue à a_->3- si vous utilisez a_:>a, cela reste ainsi et a=3;5/.{a_:>a}revient 5).
JungHwan Min
J'ai marqué votre réponse comme non concurrente car elle ne fait pas ce que la question spécifie (trier par code de caractère, pas dans l'ordre canonique).
JungHwan Min
@JungHwanMin corrigé sur RuleDelayed. Merci.
spacemit
2

Brainf * ck , 458 226 octets

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

Essayez-le en ligne! - BF

Numberwang , 262 226 octets

8400000087111111442111911170004000400000071114002241202271214020914070419027114170270034427171114400000091111112711170000007000400040000007111400224120227121402091407041902711417027004219190071420091171411111170007000771111117

Essayez-le en ligne! - NW

Je mets les deux ici parce qu'ils sont du code identique.

JungHwan Min
la source
2

PHP, 83 octets

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

Malheureusement, vous ne pouvez pas en avoir unsetdans un ternaire, j'ai donc besoin d'utiliser le long ennuyeux array_filter.
Utilisez comme:

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:"
user59178
la source
2

Python 2, 70 octets

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

Essayez-le en ligne

C'est très inefficace. Le lien de test change le i>>7eni>>5 et définit la limite de récursivité à 10000. Suppose que les entrées n'ont que des valeurs ASCII jusqu'à 126.

Utilise l'astuce div-mod pour parcourir deux boucles: nombre minimum i/128dans la boucle externe et valeurs ASCIIi%128 dans la boucle interne. Inclut un caractère cavec la valeur ASCII donnée si le nombre de fois où il apparaît dans la chaîne est au moins son nombre minimum.

Le code utilise une astuce pour simuler l'affectation c=chr(i%128)afin qu'elle puisse être référencée dans l'expression (s.count(c)>i>>7)*c. Pythonlambda n'autorisent pas l'affectation car ils ne prennent que des expressions. Conversion en undef programme complet est toujours une perte nette ici.

Au lieu de cela, la fonction transmet la valeur chr(i%128)au prochain appel récursif en tant qu'entrée facultative. Ceci est désactivé d'une iunité car a été incrémenté, mais n'a pas d'importance tant que la chaîne ne contient pas de caractère spécial '\x7f'(nous pourrions également augmenter de 128 à 256). L'initiale c=''est inoffensive.

xnor
la source
2

V , 37 36 octets

Merci @DJMcMayhem pour l'octet!

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

Essayez-le en ligne!

Pas sûr que j'aime le regex à la fin, mais je devais faire le ò pause d'une manière ou d'une autre.

Explique

Í./&ò                    #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
nmjcman101
la source
Íî(ou :%s/\n//g) est plus courte queVGgJ
DJMcMayhem
1

Perl 6 , 68 octets

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

J'ai été un peu surpris de constater qu'il n'y a aucun moyen intégré de regrouper des éléments similaires dans une liste. C'est ce que fait le bit squish-map.

Sean
la source
1
J'obtiens "Cette séquence a déjà été itérée" sauf si je renomme aen @a(+2 octets). En outre, grep *eq$_,on peut écrire grep $_,(-3 octets) car une chaîne est une puce matcher valide.
smls
1
{[~] flat roundrobin |.comb.classify(~*){*}.sort»[*]}- Cette variation n'est que de 54 octets.
smls
@smis Je ne vois pas cette erreur. Peut-être que nous utilisons des versions différentes? Je suis sur rakudo-star-2016.10. Quoi qu'il en soit, votre solution fait honte à la mienne, vous devez la poster en tant que réponse distincte.
Sean
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.
smls
1

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>

George Reith
la source
1+~~ is the same as -~.
Neil
@Neil Awesome thanks -2 bytes
George Reith
1

Perl 6 , 54 octets

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

Explication:

  • { }: Un lambda qui prend un argument - par exemple 21211.
  • .comb: Divise l'argument d'entrée en une liste de caractères - par exemple (2,1,2,1,1).
  • .classify(~*): Groupez les caractères en utilisant la comparaison de chaînes comme condition de regroupement, en retournant un Hash non ordonné - par exemple { 2=>[2,2], 1=>[1,1,1] }.
  • {*}: Retourne une liste de toutes les valeurs du Hash - par exemple [2,2], [1,1,1].
  • .sort: Trier - par exemple [1,1,1], [2,2].
  • »[*]: Supprimez les conteneurs d'articles dans lesquels les tableaux ont été enveloppés en raison de leur présence dans le hachage, de sorte qu'ils ne seront pas considérés comme un seul élément à l'étape suivante, par exemple (1,1,1), (2,2).
  • roundrobin |: Zip les sous-listes jusqu'à épuisement - par exemple (1,2), (1,2), (1).
  • flat: Aplatissez le résultat - par exemple 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.)

smls
la source
1

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.

Emigna
la source
1

FSharp, 194 190 170 140 133 bytes

let f=Seq.map
let(@)=(>>)
f int@Seq.groupBy id@f(snd@Seq.mapi((*)128@(+)))@Seq.concat@Seq.sort@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

Cyclic3
la source
0

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``)

Patrick Roberts
la source
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) :-)
Stewie Griffin
0

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.

NikoNyrh
la source
0

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}
Value Ink
la source