Bem ... existem 59 (agora 60) perguntas com a tag classificação , mas não há quicksorts simples.
Isso deve ser consertado.
Para aqueles que não estão familiarizados com o quicksort , aqui está um detalhamento, cortesia da Wikipedia-
- Escolha um elemento, chamado de pivô , da matriz.
- Reordene a matriz para que todos os elementos com valores menores que o pivô venham antes do pivô, enquanto todos os elementos com valores maiores que o pivô venham depois dele (valores iguais podem ser usados de qualquer maneira). Após essa partição, o pivô está em sua posição final. Isso é chamado de operação de partição.
- Aplique recursivamente as etapas acima ao subconjunto de elementos com valores menores e separadamente ao subconjunto de elementos com valores maiores.
Regras
As regras são simples:
- Implemente um quicksort numérico na linguagem de programação de sua escolha.
- O pivô deve ser escolhido aleatoriamente ou com mediana de três (1º, último e médio elemento).
- Seu programa pode ser um programa ou função completa.
- Você pode obter a entrada usando STDIN, argumentos de linha de comando ou parâmetros de função. Se estiver usando uma entrada de sequência, a entrada será separada por espaço.
- A entrada pode conter valores decimais e negativos. No entanto, não haverá duplicatas.
- Você pode enviar para STDOUT ou retornando da função.
- Nenhuma função de classificação interna (ou relacionada à classificação) ou brechas padrão.
- A lista pode ter um comprimento arbitrário.
Bônus nº 1: em listas ou sub-listas de comprimento <= 5, use a classificação por inserção para acelerar um pouco as coisas. Recompensa: -15%.
Bônus # 2: se o seu idioma suportar simultaneidade, classifique a lista em paralelo. Se você estiver usando uma classificação de inserção em sub-listas, a classificação final de inserção não precisará ser paralela. Pools de encadeamentos embutidos / agendamento de encadeamentos são permitidos. Recompensa: -15%.
Nota: A mediana de três estava confundindo algumas pessoas, então aqui está uma explicação, cortesia da (novamente) Wikipedia:
escolhendo a mediana do primeiro, meio e último elemento da partição para o pivô
Pontuação
Isso é código-golfe . A pontuação base está em bytes. Se você recebeu um bônus, retire 15% desse número. Se você tiver os dois, tire 30% de desconto. Isso realmente soa como um discurso de vendas.
Não se trata de encontrar a resposta mais curta em geral, mas a mais curta em cada idioma.
E agora, uma cópia sem vergonha do snippet da tabela de classificação.
The Leaderboard
O snippet de pilha na parte inferior desta postagem gera o catálogo a partir das respostas a) como uma lista da solução mais curta por idioma eb) como uma tabela geral de líderes.
Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:
## Language Name, N bytes
onde N é o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:
## Ruby, <s>104</s> <s>101</s> 96 bytes
Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou você deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:
## Perl, 43 + 2 (-p flag) = 45 bytes
Você também pode transformar o nome do idioma em um link que será exibido no snippet:
## [><>](http://esolangs.org/wiki/Fish), 121 bytes
/* Configuration */
var QUESTION_ID = 62476; // Obtain this from the url
// It will be like http://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 41505; // This should be the user ID of the challenge author.
/* App */
var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page;
function answersUrl(index) {
return "http://api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}
function commentUrl(index, answers) {
return "http://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}
function getAnswers() {
jQuery.ajax({
url: answersUrl(answer_page++),
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function (data) {
answers.push.apply(answers, data.items);
answers_hash = [];
answer_ids = [];
data.items.forEach(function(a) {
a.comments = [];
var id = +a.share_link.match(/\d+/);
answer_ids.push(id);
answers_hash[id] = a;
});
if (!data.has_more) more_answers = false;
comment_page = 1;
getComments();
}
});
}
function getComments() {
jQuery.ajax({
url: commentUrl(comment_page++, answer_ids),
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function (data) {
data.items.forEach(function(c) {
if (c.owner.user_id === OVERRIDE_USER)
answers_hash[c.post_id].comments.push(c);
});
if (data.has_more) getComments();
else if (more_answers) getAnswers();
else process();
}
});
}
getAnswers();
var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+(?:.\d+)?)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;
var OVERRIDE_REG = /^Override\s*header:\s*/i;
function getAuthorName(a) {
return a.owner.display_name;
}
function process() {
var valid = [];
answers.forEach(function(a) {
var body = a.body;
a.comments.forEach(function(c) {
if(OVERRIDE_REG.test(c.body))
body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
});
var match = body.match(SCORE_REG);
if (match)
valid.push({
user: getAuthorName(a),
size: +match[2],
language: match[1],
link: a.share_link,
});
else console.log(body);
});
valid.sort(function (a, b) {
var aB = a.size,
bB = b.size;
return aB - bB
});
var languages = {};
var place = 1;
var lastSize = null;
var lastPlace = 1;
valid.forEach(function (a) {
if (a.size != lastSize)
lastPlace = place;
lastSize = a.size;
++place;
var answer = jQuery("#answer-template").html();
answer = answer.replace("{{PLACE}}", lastPlace + ".")
.replace("{{NAME}}", a.user)
.replace("{{LANGUAGE}}", a.language)
.replace("{{SIZE}}", a.size)
.replace("{{LINK}}", a.link);
answer = jQuery(answer);
jQuery("#answers").append(answer);
var lang = a.language;
lang = jQuery('<a>'+lang+'</a>').text();
languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang, user: a.user, size: a.size, link: a.link};
});
var langs = [];
for (var lang in languages)
if (languages.hasOwnProperty(lang))
langs.push(languages[lang]);
langs.sort(function (a, b) {
if (a.lang_raw.toLowerCase() > b.lang_raw.toLowerCase()) return 1;
if (a.lang_raw.toLowerCase() < b.lang_raw.toLowerCase()) return -1;
return 0;
});
for (var i = 0; i < langs.length; ++i)
{
var language = jQuery("#language-template").html();
var lang = langs[i];
language = language.replace("{{LANGUAGE}}", lang.lang)
.replace("{{NAME}}", lang.user)
.replace("{{SIZE}}", lang.size)
.replace("{{LINK}}", lang.link);
language = jQuery(language);
jQuery("#languages").append(language);
}
}
body { text-align: left !important}
#answer-list {
padding: 10px;
width: 290px;
float: left;
}
#language-list {
padding: 10px;
width: 290px;
float: left;
}
table thead {
font-weight: bold;
}
table td {
padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">
<div id="language-list">
<h2>Shortest Solution by Language</h2>
<table class="language-list">
<thead>
<tr><td>Language</td><td>User</td><td>Score</td></tr>
</thead>
<tbody id="languages">
</tbody>
</table>
</div>
<div id="answer-list">
<h2>Leaderboard</h2>
<table class="answer-list">
<thead>
<tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr>
</thead>
<tbody id="answers">
</tbody>
</table>
</div>
<table style="display: none">
<tbody id="answer-template">
<tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
</tbody>
</table>
<table style="display: none">
<tbody id="language-template">
<tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
</tbody>
</table>
Respostas:
C ++,
440,3405388 bytes518 bytes - bônus de 15% para classificação de inserção = 440,3 bytes477 bytes - bônus de 15% para classificação de inserção = 405,45 bytes474 bytes - bônus de 15% para classificação de inserção = 402,9 bytesAgradecemos ao @Luke por salvar 3 bytes (2 realmente).
Obrigado a @ Dúthomhas por salvar 18 (15 realmente) bytes.
Note que eu sou novo aqui e este é o meu primeiro post.
Este é um
.h
arquivo (cabeçalho).Código compactado:
Código completo:
fonte
#include
.srand(time(NULL));
Você ainda receberá números pseudo-aleatóriosrand()
.APL,
4942 bytesIsso cria uma função monádica recursiva sem nome que aceita uma matriz à direita. Não se qualifica para o bônus.
Explicação:
Experimente online
Corrigido um problema (ao custo de 8 bytes) graças ao marinus e salvou 7 bytes graças ao Thomas Kwa!
fonte
C ++ 17,
254199195 bytesCom espaço em branco:
fonte
for (y : a)
caso contrário, precisaria serfor (auto y : a)
oufor (int y : a)
. (Na verdade,clang++
chama isso de extensão C ++ 1z , mas realmente não parece ser C ++ 17? Eu não sei, e é tarde da noite para procurá-lo.)Pitão, 25 bytes
Isso define uma função
y
, que recebe uma lista de números como entrada.Experimente online: Demonstração
Explicação
Pitão, 21 bytes (provavelmente inválido)
Eu uso o método "agrupar por", que usa internamente uma classificação. Eu o uso para dividir a lista original em três sublistas (todos os elementos menores que o pivô, o pivô e todos os elementos maiores que o pivô). Sem a classificação em "agrupar por", ele poderia retornar essas 3 listas em uma ordem diferente.
Como dito, isso provavelmente é inválido. No entanto, vou mantê-lo aqui, porque é uma solução interessante.
Experimente online: Demonstração
Explicação
fonte
> <> (FISH),
313309 bytesDemorei muito para escrever. Você pode tentar aqui , basta colocar a lista que deve ser classificada na pilha inicial, separada por vírgulas, antes de executar o programa.
Como funciona
O programa pega o primeiro, o meio e o último elemento na pilha inicial e calcula a mediana desses três.
Em seguida, altera a pilha para:
elemento [lista 1] [lista 2]
onde tudo na lista 1 é menor ou igual ao elemento e tudo na lista 2 é maior.
Repete recursivamente esse processo na lista 1 e na lista 2 até que toda a lista seja classificada.
fonte
CJam, 40 bytes
Essa é uma função nomeada que espera uma matriz na pilha e envia uma em retorno.
Experimente on-line no intérprete CJam .
O código acima segue as especificações o mais próximo possível. Se isso não for necessário, 12 bytes podem ser salvos:
fonte
Python 3,
123, 122.Guardado 1 byte graças a Aaron.
Esta é a primeira vez que me preocupo em escrever um algoritmo de classificação. Na verdade, é um pouco mais fácil do que eu pensava.
Ungolfed:
fonte
<=
comparação - não garante quep
esteja no lugar certo, você provavelmente precisará mudar isso para uma desigualdade exclusiva e adicionarp
no meio de forma independente (eu não testei / posso teste o código).[2, 1, 3]
iria quebrá-lo em 1/3 do tempo, pois quando ele seleciona o pivô para 2, a lista é baixa[2, 1]
- desculpe-me por não poder testar isso agora.Javascript (ES2015), 112
Explicação
fonte
Rubi,
8760 bytesUngolfed:
Teste:
fonte
Oitava,
7675 bytesVersão multilinhas:
fonte
Julia, 83 bytes
Isso cria uma função recursiva
Q
que aceita uma matriz e retorna uma matriz. Ele não usa condicionalmente a classificação por inserção, portanto, nenhum bônus se aplica.Ungolfed:
Foi corrigido um problema e salvou alguns bytes graças ao Glen O!
fonte
f
quando usar pela primeira vezfilter
e usando emendof
vez delength
.Q(x)=endof(x)<2?x:(p=rand(x);[Q((f=filter)(i->i<p,x));p;Q(f(i->i>p,x))])
R, 78 bytes
Isso cria uma função recursiva
Q
que aceita um vetor e retorna um vetor. Não aplica condicionalmente a classificação de inserção, portanto, não há bônus.Ungolfed:
Experimente online
Economizou 4 bytes graças ao flodel!
fonte
K, 41 bytes
Tome isso, APL !!! Não faz nenhum dos bônus.
fonte
Haskell,
137136 bytesA versão ungolfed está abaixo, com nomes expandidos de variáveis e funções e alguns resultados intermediários adicionados:
Estou aproveitando o fato de que não há duplicatas para usar duas comparações estritas. Vou ter que verificar se
Data.List.partition
isso não torna as coisas mais curtas, mesmo considerando que eu teria que adicionar uma declaração de importação. Não estou aceitando o bônus de classificação de inserção porque consideroData.List.insert
uma função relacionada à classificação - portanto, proibida - e, se não a estiver usando, adicionar a classificação de inserção leva o código a 246 bytes, 209,1 com o bônus, por isso não vale a pena.Edit: Obrigado ao RobAu por sua sugestão de criar um alias para usar
f=filter
. Pode economizar apenas um byte, mas tudo ajuda.fonte
f=filter
pode cortar alguns bytes.q$f(>n)l
eq$f(<n)l
?Tcl, 138 bytes
Este é um quicksort extremamente padrão.
O pivô é simplesmente o primeiro elemento de cada sub-matriz (eu afirmo que este é um número aleatório. Https://xkcd.com/221/ )
Não é particularmente eficiente em termos de uso de memória, embora possa ser melhorado com
tailcall
a segunda recursão e um caso base de n <1 elementos.Aqui está a versão legível:
Funciona em todas as entradas e permite duplicatas. Oh, também é estável . Você pode testá-lo com algo simples, como:
Apreciar! : O)
fonte
foreach
porlmap
JavaScript (ES6), 191
fonte
Ceilão (apenas JVM),
183170Nenhum bônus se aplica.
Parece que não há uma maneira multiplataforma de produzir um número aleatório no Ceilão, portanto, isso é apenas JVM. (No final, tenho uma versão não aleatória que também funciona em JS e é menor.)
Isso define uma função que pega uma iterável de flutuadores e retorna uma versão classificada dela.
Se (contra a especificação) entradas duplicadas forem passadas, essas serão filtradas.
São 183 bytes:
import ceylon.math.float{r=random}{Float*}q({Float*}l){if(exists p=l.getFromFirst((r()*l.size).integer)){return q(l.filter((e)=>e<p)).chain{p,*q(l.filter((e)=>p<e))};}else{return[];}}
Podemos melhorar um pouco usando a nova
if
expressão (Ceylon 1.2) :São 170 bytes:
import ceylon.math.float{r=random}{Float*}q({Float*}l)=>if(exists p=l.getFromFirst((r()*l.size).integer))then q(l.filter((e)=>e<p)).chain{p,*q(l.filter((e)=>p<e))}else[];
Aqui está uma versão não aleatória:
Sem espaços, isso seria 107 bytes:
{Float*}r({Float*}l)=>if(exists p=l.first)then r(l.filter((e)=>e<p)).chain{p,*r(l.filter((e)=>p<e))}else[];
fonte
AutoIt ,
320,45304,3 bytesIsso é bastante rápido (para o AutoIt de qualquer maneira). Qualifica-se para o bônus de ordenação por inserção. Acrescentará explicação após a ocorrência do golfe final.
Entrada é
q(Array, StartingElement, EndingElement)
.Entrada + saída de teste aleatório:
fonte
Java, 346 bytes
Código compactado:
Código completo:
fonte
Mathematica,
9390 bytesSem bônus, ainda não há uma maneira mínima de classificar a inserção. Quando eu estava aprendendo C ++ recentemente, fiz uma comparação de vários algoritmos de classificação aqui .
fonte
Python2, 120 bytes
if[]==a[1:]
é exatamente enquanto,if len(a)>2
mas parece mais jogado.fonte
Lua, 242 bytes
Ungolfed & Explination
fonte
Raquete 121 bytes
Ungolfed (l = lista, h = cabeça (primeiro elemento), t = cauda (elementos restantes ou restantes)):
Teste:
Saída:
fonte
Japonês , 23 bytes
Cada bônus precisaria ter três bytes ou menos para compensar a pontuação total, por isso não recebi nenhum bônus.
Experimente online!
fonte