Tri d'une liste de chaînes sans utiliser de méthode de tri intégrée

12

Le but de ce Code Golf est de créer un programme qui trie une liste de chaînes (par ordre croissant), sans utiliser de méthode de tri intégrée (comme Array.Sort()en .NET, sort()en PHP, ...). Notez que cette restriction exclut l'utilisation d'une méthode intégrée qui trie un tableau en ordre décroissant, puis en inversant le tableau.

Quelques détails:

  • Votre programme doit demander une entrée, et cette entrée est une liste de chaînes contenant uniquement des caractères alphabétiques en minuscules ASCII a-z, séparés par des virgules sans espaces. Par exemple:

    code,sorting,hello,golf
    
  • La sortie doit être la liste donnée de chaînes, mais triée par ordre croissant, toujours séparée par des virgules sans espaces. Par exemple:

    code,golf,hello,sorting
    
ProgramFOX
la source

Réponses:

3

GolfScript, 26 25 octets

","/.,{{.2$<{\}*}*]}*","*

Implémentation simple de Bubble Sort.

Essayez-le en ligne dans Web GolfScript .

Comment ça fonctionne

","/     # Split the input string at commas.
.,       # Get the number of chunks.
{        # Do that many times:
  {      #   Reduce; for each element but the first:
    .2$< #     Push 1 if the last two strings are in descending order, 0 if not.
    {\}* #     Swap these strings that many times.
  }*]    #   Collect the strings dumped by reduce in an array.
}*       #
","*     # Join, separating by commas.
Dennis
la source
Agréable! Accepter celle-ci comme réponse car elle est plus courte que celle actuellement acceptée.
ProgramFOX
10

Ruby 76 54 51 caractères

x=gets.scan /\w+/;$><<x.dup.map{x.delete(x.min)}*?,
Tyler Holien
la source
1
Très sympa, bogosort : D
Poignée de porte
1
Wow, maintenant c'est encore plus intéressant! J'ai dû regarder cela pendant un moment avant de réaliser ce qui se passait. Je suppose que maintenant c'est une légère variation du type de sélection: P
Poignée de porte
1
Étant donné que les éléments sont garantis d'être des caractères alpha:x=gets.scan /\w+/
Steven Rumbalski
7

k (16 caractères)

Ne respecte probablement pas vraiment l'esprit du problème. En k, il n'y a pas d' opérateur de tri intégré . <xrenvoie une liste d'index des éléments en x dans l'ordre trié.

{x@<x}[","\:0:0]
skeevey
la source
Eh bien, c'est une sorte de tri intégré, donc malheureusement, je ne peux pas marquer cela comme une réponse. J'aime bien l'idée, alors +1!
ProgramFOX
4

SED, 135

s/.*/,&,!,abcdefghijklmnopqrstuvwxyz/;:;s/\(,\([^,]*\)\(.\)[^,]*\)\(.*\)\(,\2\(.\)[^,]*\)\(.*!.*\6.*\3\)/\5\1\4\7/;t;s/^,\(.*\),!.*/\1/

Basé sur mon entrée de tri précédente

Hasturkun
la source
3

Ruby, 99 caractères ( type Gnome )

a=gets.scan /\w+/
p=1
while a[p]
a[p]>a[p-1]?p+=2:(a[p],a[p-1]=a[p-1],a[p])
p-=1if p>1
end
$><<a*?,

Cela bat à peine mon implémentation de type bulle:

Ruby, 110 104 101 caractères ( genre Bubble )

s=gets.scan /\w+/
(z=s.size).times{(0..(z-2)).map{|i|s[i],s[i+1]=s[i+1],s[i]if s[i]>s[i+1]}}
$><<s*?,

Cela fait des list.lengthitérations, car le pire des cas prend des list.length - 1itérations et une autre n'a pas vraiment d'importance, et enregistre 2 caractères.

Juste pour le plaisir, une version Quicksort:

Ruby, 113 caractères ( Quicksort )

q=->a{if a[1]
p=a.shift
l=[]
g=[]
a.map{|x|(x>p ?g:l).push x}
q[l]+[p]+q[g]
else
a
end}
$><<q[gets.scan /\w+/]*?,
Poignée de porte
la source
J'ai trouvé que cette implémentation du tri gnome boucle indéfiniment lorsque les éléments d'entrée ne sont pas tous uniques, par exemple ab b.
Scott Leadley
3

Haskell, 141

import Data.List
m=minimum
s[]=[]
s l=m l:s(l\\[m l])
t[]=[]
t s=let(a,b)=span(/=',')s in a:t(drop 1 b)
main=interact$intercalate",".s.t.init

Au moins, c'est ... en quelque sorte efficace.

Ry-
la source
Vous pouvez enregistrer 11 caractères en utilisant le tri par sélection: m=minimum s[]=[] s l=m l:(s$l\\[m l])(remplacez vos lignes 2 à 4 par ces lignes).
user3389669
Le initne semble pas être nécessaire car il n'y a ni fin ,ni fin de ligne. t s=let(a,b)=span(/=',')s in a:t(drop 1 b)peut être raccourcie en utilisant un agent de motif, en utilisant (>',')et en déposant l'espace entre 1 b: t s|(a,b)<-span(>',')s=a:t(drop 1b).
Laikoni
L'utilisation de l'insertion avec la fonction d'insertion x#(y:r)|y<x=y:x#r;x#r=x:rest plus courte. Il peut être utilisé directement dans tet comme il n'utilise pas (\\)et intercalate","peut être remplacé par tail.((',':)=<<), l'importation peut être supprimée. Tous ensemble 101 octets: essayez-le en ligne!
Laikoni
2

vba, 165

Sub q()
c=","
s=InputBox("?")
Z=Split(s, c)
t=UBound(Z)
For i=1 To t-1
For j=i To t
If Z(i)>Z(j) Then a=Z(i):Z(i)=Z(j):Z(j)=a
Next
Next
Debug.Print Join(Z,c)
End Sub
SeanC
la source
Je compte 165 caractères ...
Poignée de porte
@ Doorknob, fixed count ... Le script greasemonkey m'a évidemment donné le mauvais compte pendant que je tapais le code.
SeanC
1
Vous pouvez vous débarrasser d'un espace là-dedans Split.
Ry-
L'utilisation c=","et l'appel de cdeux fois s'ajoutent en fait au nombre d'octets dans ce cas, contribuant à 7 octets au nombre d'octets, alors qu'en utilisant simplement "," deux fois contribueraient 6 octets. Vous pouvez réduire votre code d'octet en saisissant directement le sous-appel ( sub q(s)) et en supposant que s est de type variant \ string. Vous pouvez perdre un octet de plus en passant For i=1 toà for i=1To. vous pouvez perdre 5 octets en passant Debug.Print Join...àDebug.?Join...
Taylor Scott
2

Scala, 122 octets

En une ligne (88 octets):

.permutations.filter(_.sliding(2).map(w=>w(0)<w.last).fold(true)((a,b)=>a&&b)).toSeq(0)

(il triera une liste en faisant simplement list.permutations.fil...)

En tant que programme (122 octets):

println(readLine.split(",").toSeq.permutations.filter(_.sliding(2).map(w=>w(0)<w.last).fold(true)((a,b)=>a&&b)).toSeq(0))

Une version plus longue si vous voulez qu'elle soit lue depuis stdin.

Cette itération sur toutes les permutations de la liste donnée jusqu'à ce qu'elle tombe sur une liste triée. Ce n'est pas rapide car il faut environ 12 secondes pour trier une liste de 10 éléments et bien plus d'une minute pour une liste de 11 éléments.

Les éléments [Modifier] doivent être uniques ou <peuvent être remplacés par <=. Aussi, désolé pour necro.

gan_
la source
1

javascript 128

a=prompt().split(',');b=[];for(i in a){b.push(a[i]);k=0;for(j in b){j=k;b[j]>a[i]?[c=b[j],b.splice(j,1),b.push(c)]:k++}}alert(b)

DEMO violon .

je cherche un moyen d'éliminer b.

Refroidisseur de mathématiques
la source
Retirez le []contour de la pièce après le ?pour enregistrer 2 caractères
Poignée de porte
@Doorknob je l'ai essayé avant de l'obtenir SyntaxError: missing : in conditional expressionparce que ?:;(la sténographie if/else) n'est censée prendre que deux morceaux de code à exécuter (c'est-à-dire true?b++:b--;) en utilisant [, ]est un hack, je ne sais toujours pas pourquoi cela fonctionne, je pense que c'est compris comme un tableau vide , comme placer une chaîne ou un nombre aléatoire en tant que commande autonome. mais vous pouvez toujours vous sentir libre de voter.
Math chiller
Hmm, je suppose que je me suis trompé. L'opérateur virgule peut exécuter plusieurs morceaux de code à la fois. L'utilisation des parenthèses fonctionne, donc je suppose que la ?:priorité de l' opérateur est inférieure à,
Poignée de porte
Non, as-tu essayé? Les parenthèses fonctionnent toujours ...
Poignée de porte
@ Doorknob votre droit , mais j'ai essayé {, }et cela n'a pas fonctionné - je comprends SyntaxError: missing : after property id. quant à la priorité, les parenthèses sont toujours les premières. je voudrais toujours un upvote ....
Math chiller
1

PHP 83 octets

<?for($x=fgetcsv(STDIN);$x;)${$x[0]>min($x)?x:a}[]=array_shift($x)?><?=join(~Ó,$a);

Une implémentation O (n 3 ) d'un tri de sélection. C'est le Ócaractère 211; une virgule inversée.

Exemple d'utilisation:

$ more in.dat
code,sorting,hello,golf

$ php list-sort.php < in.dat
code,golf,hello,sorting
primo
la source
1

Python 3 (80 caractères)

l=input().split(',')
m=[]
while l:m+=[l.pop(l.index(min(l)))]
print(','.join(m))

Voici une variation de l'instruction while qui est de longueur égale:

while l:x=min(l);m+=[x];l.remove(x)
Steven Rumbalski
la source
1

Mathematica 66 56

Row[#[[Ordering@#]]&[InputString[]~StringSplit~","],","]

Quelques autres solutions sans le symbole intégré Ordering:

Bogosort: 84 74

NestWhile[RandomSample,InputString[]~StringSplit~",",!OrderedQ@#&]~Row~","

Tri par bulles: 93 83

Row[InputString[]~StringSplit~","//.{x___,i_,j_,y___}/;j~Order~i==1:>{x,j,i,y},","]

Une autre solution aussi inefficace que le bogosort: 82 72

#~Row~","&/@Permutations[InputString[]~StringSplit~","]~Select~OrderedQ;
alephalpha
la source
0

R

Tri des bulles: 122 118 caractères

a=scan(,"",sep=",");h=T;while(h){h=F;for(i in 1:(length(a)-1)){j=i+1;if(a[i]>a[j]){a[j:i]=a[i:j];h=T}}};cat(a,sep=",")

Bogosort: 100 caractères

a=scan(,"",sep=",");while(any(apply(embed(a,2),1,function(x)x[1]<x[2]))){a=sample(a)};cat(a,sep=",")
plannapus
la source
0

Perl, 159

perl -F"," -lape "$m=$m<length()?length():$m for@F;$_{10**(2*$m)*sprintf'0.'.'%02d'x$m,map-96+ord,split//}=$_ for@F;$_=join',',map$_{$_+0},grep exists$_{$_+0},'0'.1..'0'.10**100"

Cela n'a jamais eu de chance de gagner, mais j'ai décidé de la partager parce que j'aimais la logique même si c'est un bordel :) L'idée derrière, c'est de convertir chaque mot en un entier (fait en utilisant la fonction ord ), on enregistre le nombre comme clé dans un hachage et la chaîne comme valeur, puis nous itérons de plus en plus à travers tous les entiers (1..10 ** 100 dans ce cas) et de cette façon nous obtenons nos chaînes triées.

AVERTISSEMENT : n'exécutez pas ce code sur votre ordinateur, car il parcourt des trillions + d'entiers. Si vous voulez le tester, vous pouvez abaisser la limite de plage supérieure et saisir des chaînes non longues. Si, pour une raison quelconque, cela est contraire aux règles, veuillez me le faire savoir et je supprimerai l'entrée!

psxls
la source
0

JS: 107 caractères - Bubble Sort

a=prompt().split(/,/);for(i=a.length;i--;)for(j=0;j<i;)a[j]>a[j+1]?[b=a[j],a[j]=a[++j],a[j]=b]:j++;alert(a)

J'ai regardé la réponse de @ tryToGetProgrammingStraight et j'ai essayé de l'améliorer, mais j'ai fini par l'implémenter légèrement différemment.

Dom Hastings
la source
0

Java, 134 octets

Une méthode qui implémente Gnome Sort.

void s(String[]a){int m=a.length-1,i=0;while(i<m){while(i>=0&&a[i].compareTo(a[i+1])>0){String t=a[i];a[i]=a[i+1];a[i+1]=t;i--;}i++;}}
SuperJedi224
la source
0

Swift, 101 octets

func s(a:[String])->[String]{return a.count<2 ? a:(s(a.filter{$0<a[0]})+[a[0]]+s(a.filter{$0>a[0]}))}

Non golfé:

//quicksort
func sort(a:[String]) -> [String]
{
    //return the array if its length is less than or equal to 1
    if a.count <= 1
    {
        return a
    }
    //choose the first element as pivot
    let pivot = a[0]
    //retrieve all elements less than the pivot
    let left = a.filter{ $0 < pivot }
    //retrieve all elements greater than the pivot
    let right = a.filter{ $0 > pivot }
    //sort the left partition, append a new array containing the pivot,
    //append the sorted right partition
    return sort(left) + Array<String>(arrayLiteral: pivot) + sort(right)
}
Palle
la source
Cela ne prend pas et ne renvoie pas les chaînes au format séparé par des virgules.
Laikoni
0

𝔼𝕊𝕄𝕚𝕟, 24 caractères / 30 octets (non compétitif)

ï⇔Ĕ⍪;↻ïꝈ)ΞÿѨŗ ï,⇀$≔МƵï;Ξ

Try it here (Firefox only).

Utilisation du tri par sélection!

Explication

ï⇔Ĕ⍪;↻ïꝈ)ΞÿѨŗ ï,⇀$≔МƵï;Ξ // implicit: ï=input, Ξ=[]
ï⇔Ĕ⍪;                    // split ï along commas and set it to ï
     ↻ïꝈ)                // while ï's length > 0
         Ξÿ              // push to Ξ:
           Ѩŗ ï,⇀$≔МƵï;  // removed minimum item(s) from ï using builtin
                       Ξ // get sorted array

Supprime et pousse de manière récursive le minimum de l'entrée vers un autre tableau.

Mama Fun Roll
la source
0

Ceylan (Bogosort), 119

String s(String i)=>",".join([*i.split(','.equals)].permutations.select((p)=>!any{for([x,y]in p.paired)y<x})[0]else[]);

Essayez-le en ligne!

J'ai trouvé la permutationsméthode et je me suis donc retrouvé avec Bogosort (une variante non aléatoire).

Formaté et commenté:

// a function `s` mapping a String `i` to a String
String s(String i) =>
    // the end result is created by joining the iterable in (...).
    ",".join(
        // take the input, split it on commas, make the result a sequence.
        [*
            i.split(','.equals)   // → {String+}
           ]                      // → [String+]
        // get the iterable of all permutations of this sequence.
        // Yes, this is an iterable of O(n!) sequences (though likely
        // lazily computed, we don't need all in memory at once).
        .permutations              // → {[String+]*}
        // filter this iterable for ordered sequences.
        // Using select instead of filter makes this
        // eager instead of lazy, so we are actually iterating
        // through all n! sequences, and storing the ordered
        // ones. (All of those are equal.)
        .select(
            // this is our function to check whether this sequence
            // is ordered in ascending order.
            (p)=>
               // return if none of the following iterable of booleans is true.
                !any {
                   // This is a for-comprehension. Inside an named argument list
                   // (what we have here, although there is no name) for a
                   // function which wants an iterable, this becomes an iterable,
                   // lazily built from the existing iterable p.paired,
                   // which is just an iterable with all pairs of subsequent
                   // elements.
                      for([x,y] in p.paired)
                        // for each such pair, we evaluate this expression, which
                        // is true when the sequence is not ordered correctly.
                           y < x         // → Boolean
                        // → {Boolean*}
                    }  //   → Boolean
                 //  → Boolean([String+])
               ) // → [[String+]*]
         // we now have a sequence of (correctly sorted) sequences.
         // just take the first one.
         // If we had used `.filter` before, this would have to be `.first`.
               [0]    // → [String+]|Null
         // in case this is null, which can only happen if the original array was
         // empty, so there were no permutations, just use the empty sequence
         //  again. (Actually, split never returns an empty array, so this can't
         //  happen, but the type checker can't know that.)
               else []    // → [String*]
    // so that is what we pass to the join method.
        )   // → String
    ;

Sans le formatage et l'analyse, il ne fait que 90 octets:

String[]s(String[]i)=>i.permutations.select((p)=>!any{for([x,y]in p.paired)y<x})[0]else[];

Essayez-le en ligne!

Paŭlo Ebermann
la source
0

ruby -plaF, , 70 octets

o=[]
$F.map{|s|i=o;s.bytes{|b|i=i[b]=[*i[b]]};i[0]=s<<?,}
$_=o*''
chop

O (n), si vous prétendez que le redimensionnement et le compactage d'un tableau sont gratuits (ce n'est vraiment pas gratuit).

Nous créons un tableau imbriqué profondément et inégalement oen plaçant une chaîne avec les octets b 1 , b 2 ... b n dans le tableau à la position o [b 1 ] [b 2 ] ... [b n ]. Le résultat ressemble à[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,["a,",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, [,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ["abc,"], ["abd,"], ["abe,"]], ["ac,"], ["ad,"]],, ["c,"]]

Ensuite, nous l'aplatissons et le sortons.

histocrate
la source