Ordinamento di un elenco di stringhe senza utilizzare alcun metodo di ordinamento incorporato


12

L'obiettivo di questo Code Golf è quello di creare un programma che ordina un elenco di stringhe (in ordine crescente), senza utilizzare alcun metodo di ordinamento incorporato (come Array.Sort()in .NET, sort()in PHP, ...). Si noti che questa restrizione esclude l'utilizzo di un metodo incorporato che ordina una matrice decrescente e quindi invertire la matrice.

Alcuni dettagli:

  • Il programma dovrebbe richiedere input e questo input è un elenco di stringhe contenente solo caratteri alfabetici minuscoli ASCII a-z, separati da virgola senza spazi. Per esempio:

    code,sorting,hello,golf
    
  • L'output dovrebbe essere l'elenco di stringhe specificato, ma ordinato in ordine crescente, separato da virgole senza spazi. Per esempio:

    code,golf,hello,sorting
    

Risposte:


3

GolfScript, 26 25 byte

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

Implementazione diretta di Bubble Sort.

Provalo online in Web GolfScript .

Come funziona

","/     # 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.

Bello! Accettare questo come risposta perché è più breve di quello attualmente accettato.
Programma FOX il

10

Rubino 76 54 51 caratteri

x=gets.scan /\w+/;$><<x.dup.map{x.delete(x.min)}*?,

1
Molto bello, bogosort : D
Maniglia della porta

1
Caspita, ora è ancora più interessante! Ho dovuto guardare questo per un po 'prima di rendermi conto di ciò che stava accadendo. Suppongo che ora sia una leggera variazione del tipo di selezione: P
Maniglia della porta

1
Dal momento che gli articoli sono garantiti per essere caratteri alfa:x=gets.scan /\w+/
Steven Rumbalski,

7

k (16 caratteri)

Probabilmente non è all'altezza dello spirito del problema. In k, non esiste un operatore di ordinamento incorporato . <xrestituisce un elenco di indici di elementi in x in ordine ordinato.

{x@<x}[","\:0:0]

Bene, questo è un tipo di ordinamento integrato, quindi sfortunatamente non posso contrassegnarlo come risposta. Mi piace l'idea, tuttavia, quindi +1!
Programma FOX


3

Ruby, 99 caratteri ( ordinamento 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*?,

Questo a malapena batte la mia implementazione del bubble sort:

Rubino, 110 104 101 caratteri ( ordinamento bolle )

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

Questo fa list.lengthiterazioni, perché lo scenario peggiore prende list.length - 1iterazioni e un altro in realtà non ha importanza, e salva 2 caratteri.

Solo per divertimento, una versione di Quicksort:

Rubino, 113 caratteri ( 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+/]*?,

Ho scoperto che questa implementazione dell'ordinamento di gnome scorre all'infinito quando gli elementi di input non sono tutti unici, ad es. 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

Almeno è ... un po ' efficiente.


Puoi salvare 11 caratteri usando l'ordinamento di selezione: m=minimum s[]=[] s l=m l:(s$l\\[m l])(sostituisci le tue righe 2–4 con queste righe).
user3389669

Il initnon sembra essere necessario in quanto non esiste né una ,nuova riga finale né una nuova riga finale. t s=let(a,b)=span(/=',')s in a:t(drop 1 b)può essere abbreviato utilizzando una guardia motivo, utilizzando (>',')e rilasciando lo spazio tra 1 b: t s|(a,b)<-span(>',')s=a:t(drop 1b).
Laikoni,

L'uso dell'inserzione con la funzione di inserimento x#(y:r)|y<x=y:x#r;x#r=x:rè più breve. Può essere utilizzato direttamente in te poiché non viene utilizzato (\\)e intercalate","può essere sostituito da tail.((',':)=<<), l'importazione può essere eliminata. Tutti insieme 101 byte: provalo online!
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

Conto 165 caratteri ...
Maniglia della porta

@Doorknob, conteggio fisso ... Lo script greasemonkey evidentemente mi ha dato il conteggio sbagliato mentre stavo digitando il codice.
SeanC

1
Puoi liberarti di uno spazio in questo Split.
Ry,

Usare c=","e chiamare cdue volte in realtà aggiunge al conteggio dei byte in questo caso, contribuendo con 7 byte al conteggio dei byte, dove solo usando "" due volte contribuirebbe con 6 byte. Puoi abbassare il tuo codice byte prendendo input direttamente dalla chiamata secondaria ( sub q(s)) e supponendo che s sia di tipo variante \ stringa. Puoi perdere un altro byte cambiando For i=1 toin for i=1To. puoi perdere 5 byte cambiando Debug.Print Join...inDebug.?Join...
Taylor Scott il

2

Scala, 122 byte

Come una linea (88 byte):

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

(ordinerà un elenco semplicemente facendo list.permutations.fil...)

Come programma (122 byte):

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

Una versione più lunga se vuoi che legga da stdin.

Questo scorre su tutte le permutazioni dell'elenco dato fino a quando non inciampa su uno ordinato. Non è veloce in quanto ci vogliono circa 12 secondi per ordinare un elenco di 10 elementi e ben oltre un minuto per uno di 11 elementi.

Gli elementi [Modifica] devono essere univoci o <possono essere sostituiti da <=. Inoltre, scusate il necro.


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)

Violino DEMO .

sto cercando un modo per eliminare b.


Rimuovere il []intorno alla parte dopo il ?per salvare 2 caratteri
Maniglia della porta

@Doorknob l'ho provato prima di farlo SyntaxError: missing : in conditional expressionperché ?:;(la stenografia if/else) dovrebbe solo prendere due pecie di codice per eseguire (cioè true?b++:b--;) usando [, ]è un hack, non sono ancora sicuro del perché funzioni, penso che sia inteso come un array vuoto dichiarazione, come posizionare una stringa o un numero casuali come comando autonomo. ma puoi comunque sentirti libero di votare.
Chiller matematico,

Hmm, suppongo di essermi sbagliato. L'operatore virgola può eseguire più parti di codice contemporaneamente. L'uso delle parentesi funziona, quindi suppongo ?:che la precedenza dell'operatore sia inferiore a,
Maniglia della porta

No, ci hai provato? Le parentesi funzionano ancora ...
Maniglia della porta

@Doorknob hai ragione , comunque ci ho provato {, }e non ha funzionato - ho capitoSyntaxError: missing : after property id . come per le parentesi di precedenza è sempre la prima. Vorrei ancora un voto ....
Math chiller

1

PHP 83 byte

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

Un'implementazione O (n 3 ) di un ordinamento di selezione. Il Ópersonaggio è 211; una virgola invertita in bit.

Esempio di utilizzo:

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

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

1

Python 3 (80 caratteri)

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

Ecco una variazione dell'istruzione while di uguale lunghezza:

while l:x=min(l);m+=[x];l.remove(x)

1

Mathematica 66 56

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

Alcune altre soluzioni senza il simbolo integrato Ordering:

Bogosort: 84 74

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

Bubble Sort: 93 83

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

Un'altra soluzione inefficiente come bogosort: 82 72

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


0

R

Bubble Sort: 122 118 caratteri

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 caratteri

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

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"

Questo non ha mai avuto la possibilità di vincere, ma ho deciso di condividerlo perché mi è piaciuta la logica anche se è un casino :) L'idea alla base è quella di convertire ogni parola in un numero intero (fatto usando la funzione ord ), salviamo il numero come chiave in un hash e la stringa come valore, quindi ripetiamo sempre più tutti gli interi (1..10 ** 100 in questo caso) e in questo modo ordiniamo le nostre stringhe.

ATTENZIONE : non eseguire questo codice sul tuo computer, poiché scorre attraverso trilioni + di numeri interi. Se si desidera testarlo, è possibile ridurre il limite di intervallo superiore e immettere stringhe non lunghe. Se per qualsiasi motivo questo è contrario alle regole, per favore fatemi sapere e cancellerò la voce!


0

JS: 107 caratteri - 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)

Ho guardato la risposta di @ tryingToGetProgrammingStraight e ho cercato di migliorarla, ma alla fine ho implementato in modo leggermente diverso.


0

Java, 134 byte

Un metodo che 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++;}}

0

Rapido, 101 byte

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

Ungolfed:

//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)
}

Ciò non accetta e restituisce le stringhe nel formato separato da virgole.
Laikoni,

0

𝔼𝕊𝕄𝕚𝕟, 24 caratteri / 30 byte (non competitivo)

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

Try it here (Firefox only).

Usando l'ordinamento di selezione!

Spiegazione

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

Rimuove sostanzialmente ricorsivamente e spinge il minimo dall'input a un altro array.


0

Ceylon (Bogosort), 119

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

Provalo online!

Ho trovato il permutationsmetodo e quindi ho finito con Bogosort (una variante non casuale).

Formattato e commentato:

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

Senza la formattazione e l'analisi diventa solo 90 byte:

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

Provalo online!



0

ruby -plaF, , 70 byte

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

O (n), se fai finta che il ridimensionamento e la compattazione di un array sia gratuito (non è molto gratuito).

Creiamo un array annidato profondamente e in modo non uniforme oinserendo una stringa con byte b 1 , b 2 ... b n nell'array nella posizione o [b 1 ] [b 2 ] ... [b n ]. Il risultato sembra[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,["a,",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, [,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ["abc,"], ["abd,"], ["abe,"]], ["ac,"], ["ad,"]],, ["c,"]]

Quindi lo appiattiamo e lo produciamo.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.