Cóż ... istnieje 59 (obecnie 60) pytań oznaczonych sortowaniem , ale nie ma prostych szybkich sortowań.
To musi zostać naprawione.
Dla tych, którzy nie znają quicksort , oto podział, dzięki uprzejmości Wikipedia-
- Wybierz element zwany osią przestawną z tablicy.
- Zmień kolejność tablic, aby wszystkie elementy o wartościach mniejszych niż pivot znajdowały się przed pivotem, a wszystkie elementy o wartościach większych niż pivot pojawiały się po nim (równe wartości mogą iść w obie strony). Po tym podziale punkt obrotu znajduje się w końcowej pozycji. Nazywa się to operacją partycji.
- Rekurencyjnie zastosuj powyższe kroki do podgrupy elementów o mniejszych wartościach i osobno do podgrupy elementów o większych wartościach.
Zasady
Zasady są proste:
- Zaimplementuj numeryczne szybkie sortowanie w wybranym języku programowania.
- Czop powinien być wybrany losowo lub z medianą trzech (pierwszy, ostatni i środkowy element).
- Twój program może być kompletnym programem lub funkcją.
- Dane wejściowe można uzyskać za pomocą STDIN, argumentów wiersza poleceń lub parametrów funkcji. Jeśli używasz ciągu wejściowego, dane wejściowe są rozdzielane spacjami.
- Dane wejściowe mogą zawierać wartości dziesiętne i ujemne. Jednak nie będzie duplikatów.
- Możesz wyprowadzać dane do STDOUT lub wracając z funkcji.
- Brak wbudowanych funkcji sortowania (lub związanych z sortowaniem) lub standardowych luk.
- Lista może mieć dowolną długość.
Premia # 1: Na listach lub sublistach o długości <= 5 użyj sortowania wstawiania, aby nieco przyspieszyć. Nagroda: -15%.
Premia 2: Jeśli twój język obsługuje współbieżność, posortuj listę równolegle. Jeśli używasz sortowania wstawiania na podlistach, ostateczne sortowanie wstawiania nie musi być równoległe. Dozwolone są wbudowane pule wątków / planowanie wątków. Nagroda: -15%.
Uwaga: Mediana z trzech była myląca dla niektórych osób, więc oto wyjaśnienie, dzięki (ponownie) Wikipedii:
wybór mediany pierwszego, środkowego i ostatniego elementu przegrody dla osi przestawnej
Punktacja
To jest golf golfowy . Podstawowy wynik jest w bajtach. Jeśli masz jeden bonus, weź 15% zniżki na ten numer. Jeśli masz oba, weź 30% zniżki. To naprawdę brzmi jak sprzedaż.
Nie chodzi o to, by znaleźć najkrótszą odpowiedź w ogóle, ale raczej najkrótszą w każdym języku.
A teraz bezwstydna kopia fragmentu tabeli wyników.
Tabela liderów
Fragment kodu na dole tego postu generuje katalog na podstawie odpowiedzi a) jako listy najkrótszych rozwiązań dla każdego języka oraz b) jako ogólnej tabeli wyników.
Aby upewnić się, że Twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown:
## Language Name, N bytes
gdzie N jest rozmiarem twojego zgłoszenia. Jeśli poprawisz swój wynik, możesz zachować stare wyniki w nagłówku, przekreślając je. Na przykład:
## Ruby, <s>104</s> <s>101</s> 96 bytes
Jeśli chcesz umieścić w nagłówku wiele liczb (np. Ponieważ twój wynik jest sumą dwóch plików lub chcesz osobno wymienić kary za flagi tłumacza), upewnij się, że rzeczywisty wynik jest ostatnią liczbą w nagłówku:
## Perl, 43 + 2 (-p flag) = 45 bytes
Możesz także ustawić nazwę języka jako link, który pojawi się we fragmencie:
## [><>](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>
Odpowiedzi:
C ++,
440,3405388 bajtów518 bajtów - 15% premii za sortowanie za wstawienie = 440,3 bajtów477 bajtów - 15% premii za sortowanie za wstawienie = 405,45 bajtów474 bajty - 15% premii za sortowanie za wstawienie = 402,9 bajtówDzięki @Luke za oszczędność 3 bajtów (naprawdę 2).
Dzięki @ Dúthomhas za uratowanie 18 (15 naprawdę) bajtów.
Pamiętaj, że jestem tu nowy i to jest mój pierwszy post.
To jest plik
.h
(nagłówek).Skompresowany kod:
Pełny kod:
źródło
#include
.srand(time(NULL));
Nadal będziesz otrzymywać pseudolosowe numeryrand()
.APL,
4942 bajtówTworzy to bezimienną rekurencyjną funkcję monadyczną, która akceptuje tablicę po prawej stronie. Nie kwalifikuje się do premii.
Wyjaśnienie:
Wypróbuj online
Naprawiono problem (kosztem 8 bajtów) dzięki marinus i zapisano 7 bajtów dzięki Thomasowi Kwa!
źródło
C ++ 17,
254199195 bajtówZ białymi znakami:
źródło
for (y : a)
w przeciwnym razie musiałby byćfor (auto y : a)
lubfor (int y : a)
. (Właściwieclang++
nazywa to rozszerzeniem C ++ 1z , ale tak naprawdę nie wydaje się to C ++ 17? Nie wiem i jest za późno w nocy, żeby to sprawdzić.)Pyth, 25 bajtów
Definiuje funkcję
y
, która pobiera listę liczb jako dane wejściowe.Wypróbuj online: demonstracja
Wyjaśnienie
Pyth, 21 bajtów (prawdopodobnie nieprawidłowy)
Używam metody „grupuj według”, która wewnętrznie używa sortowania. Używam go, aby podzielić oryginalną listę na trzy listy podrzędne (wszystkie elementy mniejsze niż pivot, pivot i wszystkie elementy większe niż pivot). Bez sortowania według „grupowania według” mogłoby zwrócić te 3 listy w innej kolejności.
Jak powiedziano, jest to prawdopodobnie nieprawidłowa. Niemniej jednak zatrzymam go tutaj, ponieważ jest to interesujące rozwiązanie.
Wypróbuj online: demonstracja
Wyjaśnienie
źródło
> <> (Ryba),
313309 bajtówPisanie zajęło mi bardzo dużo czasu. Możesz spróbować tutaj , po prostu umieść listę, którą należy posortować, na początkowym stosie, oddzielając ją przecinkami, przed uruchomieniem programu.
Jak to działa
Program pobiera pierwszy, środkowy i ostatni element ze stosu początkowego i oblicza medianę tych trzech.
Następnie zmienia stos na:
[lista 1] element [lista 2]
gdzie wszystko na liście 1 jest mniejsze lub równe elementowi, a wszystko na liście 2 jest większe.
Rekurencyjnie powtarza ten proces na liście 1 i liście 2, dopóki cała lista nie zostanie posortowana.
źródło
CJam, 40 bajtów
Jest to nazwana funkcja, która oczekuje tablicy na stosie i wypycha ją w zamian.
Wypróbuj online w interpretatorze CJam .
Powyższy kod jest zgodny ze specyfikacją tak dokładnie, jak to możliwe. Jeśli nie jest to wymagane, można zapisać 12 bajtów:
źródło
Python 3,
123, 122.Zaoszczędził 1 bajt dzięki Aaronowi.
To pierwszy raz, kiedy tak naprawdę zadałem sobie trud napisania algorytmu sortowania. To jest trochę łatwiejsze, niż się spodziewałem.
Nie golfowany:
źródło
<=
porównania - nie gwarantuje, żep
jest we właściwym miejscu, prawdopodobnie musisz zmienić to na wyłączną nierówność i dodaćp
niezależnie środek (nie testowałem / nie mogę testuj kod).[2, 1, 3]
to zepsuje 1/3 czasu, ponieważ gdy wybierze oś przestawną na 2, będzie miała niską listę[2, 1]
- przepraszam, że nie mogę teraz tego przetestować.JavaScript (ES2015), 112
Wyjaśnienie
źródło
Rubin,
8760 bajtówNie golfowany:
Test:
źródło
Oktawa,
7675 bajtówWersja wieloliniowa:
źródło
Julia, 83 bajty
Tworzy to funkcję rekurencyjną,
Q
która akceptuje tablicę i zwraca tablicę. Nie korzysta z warunkowego sortowania, więc nie obowiązuje żadna premia.Nie golfowany:
Naprawiono problem i zapisywano niektóre bajty dzięki Glen O!
źródło
f
przy pierwszym użyciufilter
i używającendof
zamiastlength
.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 bajtów
Tworzy to funkcję rekurencyjną,
Q
która akceptuje wektor i zwraca wektor. Nie warunkowo stosuje sortowania wstawiania, więc nie ma premii.Nie golfowany:
Wypróbuj online
Zaoszczędź 4 bajty dzięki flodel!
źródło
K, 41 bajtów
ZRÓB TO, APL !!! Nie robi żadnej z premii.
źródło
Haskell,
137136 bajtówWersja bez golfa jest poniżej, z rozszerzonymi nazwami zmiennych i funkcji oraz dodanymi niektórymi wynikami pośrednimi:
Korzystam z faktu, że nie ma duplikatów, aby użyć dwóch ścisłych porównań. Będę musiał sprawdzić, czy
Data.List.partition
to nie skraca rzeczy, nawet biorąc pod uwagę, że musiałbym dodać instrukcję importu. Nie biorę premii zaData.List.insert
sortowanie za wstawianie, ponieważ uważam ją za funkcję związaną z sortowaniem - w związku z tym jest zabroniona - a jeśli jej nie używam, dodanie sortowania za wstawianie przesuwa kod do 246 bajtów, 209,1 z premią, więc nie jest tego warte.Edycja: Podziękowania dla RobAu za sugestię utworzenia aliasu do użycia
f=filter
. Może zaoszczędzić tylko jeden bajt, ale wszystko pomaga.źródło
f=filter
może ogolić niektóre bajty.q$f(>n)l
iq$f(<n)l
wywołań?Tcl, 138 bajtów
Jest to niezwykle standardowy Quicksort.
Oś jest po prostu pierwszym elementem każdej podtablicy (twierdzę, że jest to liczba losowa. Https://xkcd.com/221/ )
Nie jest szczególnie wydajny pod względem wykorzystania pamięci, chociaż można go poprawić dzięki
tailcall
drugiej rekurencji i przypadkowi podstawowemu elementów n <1.Oto czytelna wersja:
Działa na wszystkich danych wejściowych i zezwala na duplikaty. Och, to także stabilne . Możesz to przetestować za pomocą czegoś prostego, na przykład:
Cieszyć się! : O)
źródło
foreach
przezlmap
JavaScript (ES6), 191
źródło
Ceylon (tylko JVM),
183170Nie obowiązują żadne bonusy.
Wygląda na to, że nie ma wieloplatformowego sposobu generowania losowej liczby na Cejlonie, więc jest to tylko JVM. (Na koniec mam nieprzypadkową wersję, która działa również w JS i jest mniejsza.)
Definiuje funkcję, która pobiera iterowalną liczbę zmiennoprzecinkową i zwraca jej posortowaną wersję.
Jeśli (zgodnie ze specyfikacją) zduplikowane wpisy zostaną przekazane, zostaną one odfiltrowane.
Są to 183 bajty:
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[];}}
Możemy nieco poprawić, używając nowego
if
wyrażenia (Ceylon 1.2) :To jest 170 bajtów:
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[];
Oto wersja nieprzypadkowa:
Bez spacji byłoby to 107 bajtów:
{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[];
źródło
AutoIt ,
320,45304,3 bajtówTo dość szybko (w każdym razie dla AutoIt). Kwalifikuje się do premii za sortowanie za wstawianie. Dodam wyjaśnienie po zakończeniu gry w golfa.
Dane wejściowe to
q(Array, StartingElement, EndingElement)
.Losowe wejście testowe + wyjście:
źródło
Java, 346 bajtów
Skompresowany kod:
Pełny kod:
źródło
Mathematica,
9390 bajtówBrak premii, nie mam jeszcze minimalnego sposobu na sortowanie przez wstawianie. Kiedy uczyłem się C ++ niedawno zrobiłem porównanie różnych algorytmów sortowania tutaj .
źródło
Python2, 120 bajtów
if[]==a[1:]
jest dokładnie tak długi,if len(a)>2
ale wygląda bardziej golfowo.źródło
Lua, 242 bajtów
Niegolfowane i wyjaśnienia
źródło
Rakieta 121 bajtów
Niegolfowany (l = lista, h = głowa (pierwszy element), t = ogon (reszta lub pozostałe elementy)):
Testowanie:
Wydajność:
źródło
Japt , 23 bajty
Każdy bonus musiałby mieć trzy bajty lub mniej, aby spłacić całkowity wynik, więc nie wziąłem żadnych bonusów.
Wypróbuj online!
źródło