Classificando uma lista de seqüências de caracteres sem usar nenhum método de classificação interno

12

O objetivo deste Code Golf é criar um programa que classifique uma lista de seqüências de caracteres (em ordem crescente), sem usar nenhum método de classificação interno (como Array.Sort()no .NET, sort()no PHP, ...). Observe que essa restrição exclui o uso de um método interno que classifica uma matriz descendente e, em seguida, reverte a matriz.

Alguns detalhes:

  • Seu programa deve solicitar entrada e essa entrada é uma lista de cadeias contendo apenas caracteres alfabéticos em minúsculas ASCII a-z, separados por vírgula sem espaços. Por exemplo:

    code,sorting,hello,golf
    
  • A saída deve ser a lista de cadeias fornecida, mas classificada em ordem crescente, ainda separada por vírgulas sem espaços. Por exemplo:

    code,golf,hello,sorting
    
ProgramFOX
fonte

Respostas:

3

GolfScript, 26 25 bytes

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

Implementação direta do Bubble Sort.

Experimente online no Web GolfScript .

Como 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
fonte
Agradável! Aceitar este como resposta, porque é mais curto que o atualmente aceito.
precisa
10

Ruby 76 54 51 caracteres

x=gets.scan /\w+/;$><<x.dup.map{x.delete(x.min)}*?,
Tyler Holien
fonte
1
Muito bom, bogosort : D
Maçaneta
1
Uau, agora é ainda mais interessante! Eu tive que olhar isso por um tempo antes de perceber o que estava acontecendo. Suponho que agora haja uma pequena variação no tipo de seleção: P
Maçaneta da porta
1
Como os itens são garantidos como caracteres alfa:x=gets.scan /\w+/
Steven Rumbalski 15/10
7

k (16 caracteres)

Provavelmente não corresponde ao espírito do problema. Em k, não há um operador de classificação incorporado . <xretorna uma lista de índices de itens em x na ordem classificada.

{x@<x}[","\:0:0]
skeevey
fonte
Bem, esse é um tipo de classificação interna, então, infelizmente, não posso marcar isso como resposta. Eu gosto da ideia, no entanto, então +1!
ProgramFOX
4

SED, 135

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

Com base na minha entrada de classificação anterior

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

Isso apenas supera minha implementação de classificação de bolhas:

Ruby, 110 104 101 caracteres (Classificação por bolha )

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

Isso faz list.lengthiterações, porque o pior cenário leva list.length - 1iterações e mais uma realmente não importa e salva 2 caracteres.

Apenas por diversão, uma versão do 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+/]*?,
Maçaneta da porta
fonte
Eu descobri que essa implementação do tipo gnome faz loop infinitamente quando os itens de entrada não são todos únicos, por exemplo, 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

Pelo menos é ... meio eficiente.

Ry-
fonte
Você pode salvar 11 caracteres usando a classificação de seleção: m=minimum s[]=[] s l=m l:(s$l\\[m l])(substitua suas linhas 2 a 4 por essas linhas).
user3389669
A initnão parece ser necessário, como não é nem uma fuga ,, nem uma nova linha final. t s=let(a,b)=span(/=',')s in a:t(drop 1 b)pode ser encurtado usando um guarda teste padrão, usando (>',')e soltando o espaço entre 1 b: t s|(a,b)<-span(>',')s=a:t(drop 1b).
Laikoni
O uso da inserção com a função de inserção x#(y:r)|y<x=y:x#r;x#r=x:ré mais curto. Ele pode ser usado diretamente te, como não usa (\\)e intercalate","pode ser substituído por tail.((',':)=<<), a importação pode ser descartada. Todos juntos 101 bytes: Experimente 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
SeanC
fonte
Conto 165 caracteres ...
Maçaneta da porta
@ Doorknob, contagem fixa ... O script greasemonkey evidentemente me deu a contagem errada enquanto eu digitava o código.
21313 SeanC
1
Você pode se livrar de um espaço nisso Split.
Ry-
Usar c=","e chamar cduas vezes na verdade adiciona à contagem de bytes neste caso, contribuindo com 7 bytes para a contagem de bytes, onde apenas o uso de "," duas vezes contribuirá com 6 bytes. Você pode diminuir o código de byte usando a entrada diretamente da sub-chamada ( sub q(s)) e assumindo que s é do tipo variant \ string. Você pode perder mais um byte, alterando For i=1 topara for i=1To. você pode perder 5 bytes mudando Debug.Print Join...paraDebug.?Join...
Taylor Scott
2

Scala, 122 bytes

Como uma linha (88 bytes):

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

(ele ordenará uma lista apenas fazendo list.permutations.fil...)

Como um 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))

Uma versão mais longa, se você quiser ler a partir de stdin.

Ele repete todas as permutações da lista fornecida até encontrar uma ordenada. Não é rápido, pois leva cerca de 12 segundos para classificar uma lista de 10 elementos e mais de um minuto para uma lista de 11 elementos.

Os itens [Editar] precisam ser exclusivos ou <podem ser substituídos por <=. Além disso, desculpe pelo necro.

gan_
fonte
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 violino .

Eu estou procurando uma maneira de eliminar b.

Resfriador de matemática
fonte
Remova a []parte após a peça ?para salvar 2 caracteres.
Maçaneta da porta
@Doorknob Eu tentei isso antes de começar SyntaxError: missing : in conditional expressionporque ?:;(a abreviação if/else) só deve levar dois pecies de código para executar (ie true?b++:b--;) usando [, ]é um hack, ainda não sei ao certo por que funciona, acho que é entendido como uma matriz vazia declaração, como colocar uma seqüência ou número aleatório como um comando independente. mas você ainda pode se sentir à vontade para votar.
Math chiller
Hmm, suponho que estava enganado. O operador de vírgula pode executar várias partes do código de uma só vez. Usando obras parênteses, então eu suponho que a ?:precedência do operador é inferior,
Doorknob
Não, você tentou? Parênteses ainda funcionam ...
Maçaneta da porta
@ Doorknob seu direito , no entanto eu tentei {, }e não funcionou - eu recebo SyntaxError: missing : after property id. os parênteses de precedência são sempre os primeiros. Eu ainda gostaria de um upvote ....
Math chiller
1

PHP 83 bytes

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

Uma implementação O (n 3 ) de uma classificação de seleção. O Ócaractere é 211; uma vírgula invertida.

Uso da amostra:

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

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

Python 3 (80 caracteres)

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

Aqui está uma variação da instrução while que tem o mesmo comprimento:

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

Mathematica 66 56

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

Algumas outras soluções sem o símbolo de incorporação Ordering:

Bogosort: 84 74

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

Tipo de bolha: 93 83

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

Outra solução tão ineficiente quanto bogosort: 82 72

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

R

Classificação da bolha: 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
fonte
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"

Isso nunca teve chance de ganhar, mas decidiu compartilhá-lo porque eu gostei da lógica, mesmo que seja uma bagunça :) A idéia por trás disso é converter cada palavra em um número inteiro (feito usando a função ord ), salvamos o número como uma chave em um hash e a string como um valor e, em seguida, iteramos cada vez mais todos os números inteiros (1..10 ** 100 nesse caso) e, dessa forma, classificamos nossas strings.

AVISO : Não execute esse código no seu computador, pois ele percorre trilhões + de números inteiros. Se você quiser testá-lo, poderá diminuir o limite superior do intervalo e inserir seqüências não longas. Se, por algum motivo, isso for contrário às regras, informe-me e excluiremos a entrada!

psxls
fonte
0

JS: 107 caracteres - Classificação de bolhas

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)

Eu olhei para a resposta do @TryingGetProgrammingStraight e tentei melhorá-la, mas acabei implementando-a de maneira um pouco diferente.

Dom Hastings
fonte
0

Java, 134 bytes

Um método que implementa a classificação do Gnome.

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
fonte
0

Rápido, 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]}))}

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)
}
Palle
fonte
Isso não pega e retorna as strings no formato separado por vírgula.
Laikoni
0

, 24 caracteres / 30 bytes (não competitivo)

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

Try it here (Firefox only).

Usando a classificação de seleção!

Explicação

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

Basicamente, recursivamente remove e empurra o mínimo da entrada para outra matriz.

Mama Fun Roll
fonte
0

Ceilão (Bogosort), 119

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

Experimente online!

Encontrei o permutationsmétodo e, portanto, acabei com o Bogosort (uma variante não aleatória).

Formatado e 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
    ;

Sem a formatação e análise, torna-se apenas 90 bytes:

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

Experimente online!

Paŭlo Ebermann
fonte
0

Perl 5 , 77 bytes

map{$F[$_]gt$F[$_+1]&&(@F[$_,$_+1]=@F[$_+1,$_])for 0..@F-2}@F;$_=join',',"@F"

Experimente online!

Classificação de bolha simples.

Xcali
fonte
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), se você fingir que redimensionar e compactar uma matriz é gratuito (não é muito grátis).

Criamos uma matriz aninhada profunda e desigualmente ocolocando uma string com bytes b 1 , b 2 ... b n na matriz na posição o [b 1 ] [b 2 ] ... [b n ]. O resultado parece[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,["a,",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, [,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ["abc,"], ["abd,"], ["abe,"]], ["ac,"], ["ad,"]],, ["c,"]]

Então achatamos e produzimos.

histocrata
fonte