Ordenar una lista de cadenas sin utilizar ningún método de ordenamiento incorporado

12

El objetivo de este Code Golf es crear un programa que clasifique una lista de cadenas (en orden ascendente), sin utilizar ningún método de ordenamiento incorporado (como Array.Sort()en .NET, sort()en PHP, ...). Tenga en cuenta que esta restricción excluye el uso de un método incorporado que ordena una matriz descendente y luego invierte la matriz.

Algunos detalles:

  • Su programa debe solicitar una entrada, y esta entrada es una lista de cadenas que contienen solo caracteres alfabéticos en minúsculas ASCII a-z, separados por comas y sin espacios. Por ejemplo:

    code,sorting,hello,golf
    
  • La salida debe ser la lista de cadenas dada, pero ordenada en orden ascendente, aún separada por comas sin espacios. Por ejemplo:

    code,golf,hello,sorting
    
ProgramFOX
fuente

Respuestas:

3

GolfScript, 26 25 bytes

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

Implementación directa de Bubble Sort.

Pruébelo en línea en Web GolfScript .

Cómo funciona

","/     # 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
fuente
¡Agradable! Aceptar esta como respuesta porque es más corta que la actualmente aceptada.
ProgramFOX
10

Ruby 76 54 51 caracteres

x=gets.scan /\w+/;$><<x.dup.map{x.delete(x.min)}*?,
Tyler Holien
fuente
1
Muy agradable, stupid sort : D
Pomo
1
¡Guau, ahora es aún más interesante! Tuve que mirar esto por un tiempo antes de darme cuenta de lo que estaba sucediendo. Supongo que ahora es una ligera variación del tipo de selección: P
Pomo de la puerta
1
Dado que los elementos están garantizados como caracteres alfabéticos:x=gets.scan /\w+/
Steven Rumbalski
7

k (16 caracteres)

Probablemente no esté realmente a la altura del espíritu del problema. En k, no hay un operador de ordenamiento integrado . <xdevuelve una lista de índices de elementos en x en orden ordenado.

{x@<x}[","\:0:0]
skeevey
fuente
Bueno, este es un tipo de clasificación incorporada, así que desafortunadamente, no puedo marcar esto como respuesta. Sin embargo, me gusta la idea, ¡así que +1!
ProgramFOX
4

SED, 135

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

Basado en mi entrada de clasificación anterior

Hasturkun
fuente
3

Ruby, 99 caracteres ( tipo 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*?,

Esto apenas supera mi implementación de tipo burbuja:

Ruby, 110 104 101 caracteres ( ordenamiento de burbuja )

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*?,

Esto hace list.lengthiteraciones, porque el peor de los casos toma list.length - 1iteraciones y una más realmente no importa, y guarda 2 caracteres.

Solo por diversión, una versión Quicksort:

Ruby, 113 caracteres ( 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+/]*?,
Pomo de la puerta
fuente
Descubrí que esta implementación de gnome sort bucles infinitamente cuando los elementos de entrada no son todos únicos, por ejemplo, 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

Al menos es ... algo eficiente.

Ry-
fuente
Puede guardar 11 caracteres utilizando el orden de selección: m=minimum s[]=[] s l=m l:(s$l\\[m l])(reemplace sus líneas 2–4 con estas líneas).
user3389669
El initno parece ser necesario ya que no hay ni un arrastre ,, ni un salto de línea final. t s=let(a,b)=span(/=',')s in a:t(drop 1 b)puede acortarse mediante el uso de un protector de patrón, utilizando (>',')y soltando el espacio entre 1 b: t s|(a,b)<-span(>',')s=a:t(drop 1b).
Laikoni
Usar inserción con la función de inserción x#(y:r)|y<x=y:x#r;x#r=x:res más corto. Se puede usar directamente ty, como no se usa (\\)y intercalate","se puede reemplazar tail.((',':)=<<), la importación se puede descartar. Todos juntos 101 bytes: ¡ Pruébelo en línea!
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
fuente
Cuento 165 caracteres ...
Pomo de la puerta
@Doorknob, conteo fijo ... El script greasemonkey evidentemente me dio un conteo incorrecto mientras escribía el código.
SeanC
1
Puedes deshacerte de un espacio en eso Split.
Ry-
El uso c=","y la llamada cdos veces en realidad se suman al recuento de bytes en este caso, contribuyendo con 7 bytes al recuento de bytes, mientras que simplemente usando "," dos veces contribuiría 6 bytes. Puede reducir su código de bytes tomando la entrada directamente de la llamada secundaria ( sub q(s)) y suponiendo que s es de tipo variant \ string. Puede perder un byte más cambiando For i=1 toa for i=1To. puede perder 5 bytes cambiando Debug.Print Join...aDebug.?Join...
Taylor Scott
2

Scala, 122 bytes

Como una línea (88 bytes):

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

(ordenará una lista simplemente haciendo list.permutations.fil...)

Como programa (122 bytes):

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

Una versión más larga si quieres que lea desde stdin.

Esto itera sobre todas las permutaciones de la lista dada hasta que tropieza con una ordenada. No es rápido, ya que lleva unos 12 segundos ordenar una lista de 10 elementos y más de un minuto para una de 11 elementos.

Los elementos [Editar] deben ser únicos o <pueden ser reemplazados por <=. Además, lo siento por necro.

gan_
fuente
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)

Violín DEMO .

Estoy buscando una manera de eliminar b.

Enfriador de matemáticas
fuente
Retire la []parte posterior de la parte ?para guardar 2 caracteres
Pomo de la puerta
@Doorknob Lo he intentado antes de obtenerlo SyntaxError: missing : in conditional expressionporque ?:;(la taquigrafía if/else) solo se supone que toma dos especies de código para ejecutar (es decir , true?b++:b--;usar) [, ]es un truco, todavía no estoy seguro de por qué funciona, creo que se entiende como una matriz vacía declaración, como colocar una cadena o número aleatorio como un comando independiente. pero aún puedes sentirte libre de votar.
Math chiller
Hmm, supongo que me equivoqué. El operador de coma puede ejecutar múltiples piezas de código a la vez. El uso de paréntesis funciona, así que supongo ?:que la precedencia del operador es menor que,
Pomo de la puerta
No, lo intentaste? El paréntesis sigue funcionando ...
Pomo de la puerta
@ Pomo de la puerta a la derecha , sin embargo lo intenté {, }y no funcionó , lo entiendo SyntaxError: missing : after property id. En cuanto a los paréntesis de precedencia siempre es primero. Todavía me gustaría un voto positivo ...
Math chiller
1

PHP 83 bytes

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

Una implementación O (n 3 ) de un tipo de selección. El Óes el personaje 211; una coma un poco invertida.

Uso de la muestra:

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

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

Python 3 (80 caracteres)

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

Aquí hay una variación de la declaración while que es de igual longitud:

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

Mathematica 66 56

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

Algunas otras soluciones sin el símbolo incorporado Ordering:

Bogosort: 84 74

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

Clasificación de burbujas: 93 83

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

Otra solución tan ineficiente como bogosort: 82 72

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

R

Burbuja Ordenar: 122 118 caracteres

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 caracteres

a=scan(,"",sep=",");while(any(apply(embed(a,2),1,function(x)x[1]<x[2]))){a=sample(a)};cat(a,sep=",")
plannapus
fuente
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"

Esto nunca tuvo la oportunidad de ganar, pero decidí compartirlo porque me gustó la lógica, incluso si es un desastre :) La idea detrás de esto es convertir cada palabra en un número entero (hecho usando la función ord ), guardamos el número como una clave en un hash y la cadena como un valor, y luego iteramos cada vez más a través de todos los enteros (1..10 ** 100 en este caso) y de esa manera ordenamos nuestras cadenas.

ADVERTENCIA : No ejecute este código en su computadora, ya que recorre trillones + de enteros. Si desea probarlo, puede reducir el límite superior del rango e ingresar cadenas no largas. Si por alguna razón esto va en contra de las reglas, ¡hágamelo saber y eliminaré la entrada!

psxls
fuente
0

JS: 107 caracteres - Clasificación de burbujas

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)

Miré la respuesta de @ tryingToGetProgrammingStraight e intenté mejorarla, pero terminé implementándola de manera ligeramente diferente.

Dom Hastings
fuente
0

Java, 134 bytes

Un método que implementa 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
fuente
0

Swift, 101 bytes

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

Sin 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)
}
Pálido
fuente
Esto no toma y devuelve las cadenas en el formato separado por comas dado.
Laikoni
0

𝔼𝕊𝕄𝕚𝕟, 24 caracteres / 30 bytes (no competitivo)

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

Try it here (Firefox only).

Usando la selección de clasificación!

Explicación

ï⇔Ĕ⍪;↻ïꝈ)ΞÿѨŗ ï,⇀$≔МƵï;Ξ // 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

Básicamente, elimina y empuja recursivamente el mínimo de la entrada a otra matriz.

Mama Fun Roll
fuente
0

Ceilán (Bogosort), 119

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

Pruébalo en línea!

Encontré el permutationsmétodo y así terminé con Bogosort (una variante no aleatoria).

Formateado y comentado:

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

Sin el formato y el análisis se convierte en solo 90 bytes:

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

Pruébalo en línea!

Paŭlo Ebermann
fuente
0

ruby -plaF, , 70 bytes

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

O (n), si pretende que cambiar el tamaño y compactar una matriz es gratis (no es gratis).

Creamos una matriz anidada profunda e irregularmente ocolocando una cadena con bytes b 1 , b 2 ... b n en la matriz en la posición o [b 1 ] [b 2 ] ... [b n ]. El resultado se ve como[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,["a,",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, [,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ["abc,"], ["abd,"], ["abe,"]], ["ac,"], ["ad,"]],, ["c,"]]

Luego lo aplanamos y lo sacamos.

histocrat
fuente