Klasyczne pytanie sortujące w golfa

11

To jest pytanie do golfa.

Wejście

Lista liczb całkowitych nieujemnych w dowolnym formacie jest najwygodniejsza.

Wynik

Ta sama lista w porządku posortowanym w dowolnym formacie jest najwygodniejsza.

Ograniczenie

  • Twój kod musi działać w czasie O (n log n) czasu w najgorszym przypadku , gdzie noznacza liczbę liczb na wejściu. Oznacza to, że na przykład nie ma randomizowanego szybkiego sortowania. Istnieje jednak wiele innych opcji do wyboru.
  • Nie używaj żadnej biblioteki sortującej / funkcji / podobnej. Nie używaj też niczego, co wykonuje większość sortowania, jak biblioteki sterty. Zasadniczo, cokolwiek wdrożysz, zaimplementuj go od zera.

Możesz zdefiniować funkcję, jeśli chcesz, ale następnie pokaż jej przykład w pełnym programie, który faktycznie działa. Powinien działać pomyślnie i szybko na wszystkich poniższych testach.

Przypadki testowe

In: [9, 8, 3, 2, 4, 6, 5, 1, 7, 0]
Out:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In: [72, 59, 95, 68, 84]
Out:[59, 68, 72, 84, 95]

In: [2, 2, 1, 9, 3, 7, 4, 1, 6, 7]
Out:[1, 1, 2, 2, 3, 4, 6, 7, 7, 9]

In: [2397725, 1925225, 3304534, 7806949, 4487711, 8337622, 2276714, 3088926, 4274324,  667269]
Out:[667269,1925225, 2276714, 2397725,3088926, 3304534, 4274324, 4487711, 7806949, 8337622]

Twoje odpowiedzi

Podaj zaimplementowany algorytm sortowania i długość swojego rozwiązania w tytule swojej odpowiedzi.

Algorytmy sortowania czasu O (n log n)

Istnieje wiele algorytmów czasowych O (n log n). Ta tabela zawiera listę niektórych z nich.


źródło
Niektóre ustawione funkcje, takie jak intersectautomatyczne sortowanie tablicy. Chyba też chcesz to wykluczyć. Co powiesz na unique(usuń duplikaty, posortuj wynik)?
Luis Mendo,
@DonMuesli Robię .. Myślę, że intersectjest objęty „podobnym”, jeśli automatycznie sortuje tablicę. Jeśli usuniesz duplikaty, otrzymasz nieprawidłowe dane wyjściowe.
Jeśli chodzi o podawanie niewłaściwych danych, zostaw to mnie :-) Czy można wtedy użyć „usuń duplikaty i posortuj”?
Luis Mendo
3
Nitpick: 0 nie jest dodatnią liczbą całkowitą. (Under Input )
zlewka
1
Podoba mi się, gdy tylko pytanie ma związek z wydajnością, wszyscy uciekają od języków golfowych, mimo że wciąż jest to gra w golfa kodowego, a najkrótsze rozwiązanie wciąż wygrywa.
Cyoce

Odpowiedzi:

8

Haskell, 87 80 89

s%[]=s
(x:a)%q|x<=q!!0=x:a%q
p%q=q%p
j(x:y:s)=x%y:j s
j a=a
r[x]=x
r s=r$j s
s=r.map(:[])

Jest to sortowanie scalone, realizowane od dołu do góry. najpierw pakujemy każdy element do jego własnej listy, a następnie łączymy je dwa na dwa, i ponownie łączymy je dwa na dwa, dopóki nie zostanie nam jedna lista.

(%)to funkcja scalania
jłączy pary na liście list
rłączy pełną listę list
sjest funkcją sortowania.

Sposób użycia: Uruchom tłumacza i wprowadź s [3,5,2,6,7].

Edycja: sposób, w jaki wcześniej łączyłem rzeczy, nie był prawidłowy, więc aby to naprawić, potrzebowałem jeszcze 9 znaków.

dumny haskeller
źródło
1
@Lembik, jeśli chcesz przetestować program i nie chcesz instalować Haskell, możesz użyć ideone i dodać linię podobną do main = print (s [5,3,6,8]), która ustawi główną opcję drukowania wyniku sortowania.
dumny haskeller
Myślę, że nie potrzebujesz []%s=s, ponieważ jeśli pierwszy element jest [], (x:a)dopasowanie nie powiedzie się, a ostatni przypadek odwróci elementy, więc się s%[]powiedzie.
nimi
Jesteś zwycięzcą! Jedyna odpowiedź wykorzystująca mniej bajtów nie działała w O (n log n).
@Lembik Racja, zapomniałem, że odpowiedź Jelly nie jest zgodna.
dumny haskeller 30.03.16
1
Wydaje się, że teraz :)
5

JavaScript (ES6), 195 193 191 189 188 186 183 182 179 174 172 bajtów

To implementacja heapsortu. Oczekuję, że ktoś wymyśli krótsze połączenie, ale podoba mi się ten: P.

Aktualizacja: R scalono pobity. Ruby dalej: D

S=l=>{e=l.length
W=(a,b)=>[l[a],l[b]]=[l[b],l[a]]
D=s=>{for(;(c=s*2+1)<e;s=r<s?s:e)s=l[r=s]<l[c]?c:s,W(r,s=++c<e&&l[s]<l[c]?c:s)}
for(s=e>>1;s;)D(--s)
for(;--e;D(0))W(0,e)}

Test (Firefox)

PurkkaKoodari
źródło
Chciałbym napisać krótką odpowiedź, ale tak naprawdę nie działa dobrze z Haskellem. Moja następna próba to JS, ale już to zrobiłeś. Może nadal to zrobię. Idk
dumny haskeller
@proudhaskeller Ah tak .. właśnie szukałem stackoverflow.com/a/2186785/2179021 .
3

Python3, 132 bajty

def S(l):
 if len(l)<2:return l
 a,b,o=S(l[::2]),S(l[1::2]),[]
 while a and b:o.append([a,b][a[-1]<b[-1]].pop())
 return a+b+o[::-1]

Proste połączenie. Sporo bajtów zostało wydanych, aby upewnić się, że faktycznie działa w O (n log n), jeśli tylko algorytm , ale nie implementacja musi być O (n log n), można to skrócić:

Python3, 99 bajtów

def m(a,b):
 while a+b:yield[a,b][a<b].pop(0)
S=lambda l:l[1:]and list(m(S(l[::2]),S(l[1::2])))or l

To nie jest O (n log n), ponieważ .pop(0)jest O (n), co powoduje, że funkcja scalania O (n ^ 2). Ale jest to dość sztuczne, jak .pop(0)łatwo mogło być O (1).

orlp
źródło
Dziękuję Ci za to. Zdecydowanie miałem na myśli, że algorytm i implementacja powinny być O (n log n).
Dla jasności oznacza to, że wersja 132 jest OK, ale wersja 99-bajtowa jest niezgodna.
2

Julia, 166 bajtów

m(a,b,j=1,k=1,L=endof)=[(j<=L(a)&&k<=L(b)&&a[j]<b[k])||k>L(b)?a[(j+=1)-1]:b[(k+=1)-1]for i=1:L([a;b])]
M(x,n=endof(x))=n>1?m(M(x[1:(q=ceil(Int,n÷2))]),M(x[q+1:n])):x

Wywoływana jest funkcja podstawowa, Mktóra wywołuje funkcję pomocnika m. Używa sortowania scalonego , które ma O ( n log n ) jako najgorszy przypadek złożoności.

Przykładowe zastosowanie:

x = [9, 8, 3, 2, 4, 6, 5, 1, 7, 0]
println(M(x))              # prints [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
println(M(x) == sort(x))   # prints true

Nie golfowany:

function m(a, b, i=1, k=1, L=endof)
    return [(j <= L(a) && k <= L(b) && a[j] < b[k]) || k > L(b) ?
            a[(j+=1)-1] : b[(k+=1)-1] for i = 1:L([a; b])]
end

function M(x, n=endof(x))
    q = ceil(Int, n÷2)
    return n > 1 ? m(M(x[1:q]), M([q+1:n])) : x
end
Alex A.
źródło
Miło widzieć tu Julię. Teraz potrzebujemy nim i rdzy też :)
1
@Lembik Myślę, że Sp3000 i Doorknob są naszymi rezydentami, odpowiednio, Nim i Rust. Mam nadzieję, że oni również dołączą do zabawy. ;)
Alex A.
2

R, 181 bajtów, Mergesort

L=length;s=function(S)if(L(S)<2){S}else{h=1:(L(S)/2);A=s(S[h]);B=s(S[-h]);Z=c();if(A[L(A)]>B[1])while(L(A)&L(B))if(A[1]<B[1]){Z=c(Z,A[1]);A=A[-1]}else{Z=c(Z,B[1]);B=B[-1]};c(Z,A,B)}

Wcięte, z nowymi liniami:

L=length
s=function(S)
    if(L(S)<2){
        S
    }else{
        h=1:(L(S)/2)
        A=s(S[h])
        B=s(S[-h])
        Z=c()
        if(A[L(A)]>B[1])
#Merge helper function incorporated from here ...
            while(L(A)&L(B))
                if(A[1]<B[1]){
                    Z=c(Z,A[1])
                    A=A[-1]
                }else{
                    Z=c(Z,B[1])
                    B=B[-1]
                }
#...to here. Following line both finishes merge function and handles 'else' case:
        c(Z,A,B)
    }

Przypadki testowe:

> L=length;s=function(S)if(L(S)<2){S}else{h=1:(L(S)/2);A=s(S[h]);B=s(S[-h]);Z=c();if(A[L(A)]>B[1])while(L(A)&L(B))if(A[1]<B[1]){Z=c(Z,A[1]);A=A[-1]}else{Z=c(Z,B[1]);B=B[-1]};c(Z,A,B)}
> s(c(2397725, 1925225, 3304534, 7806949, 4487711, 8337622, 2276714, 3088926, 4274324,  667269))
 [1]  667269 1925225 2276714 2397725 3088926 3304534 4274324 4487711 7806949 8337622
> s(c(2, 2, 1, 9, 3, 7, 4, 1, 6, 7))
 [1] 1 1 2 2 3 4 6 7 7 9
> s(c(72, 59, 95, 68, 84))
 [1] 59 68 72 84 95
> s(c(9, 8, 3, 2, 4, 6, 5, 1, 7, 0))
 [1] 0 1 2 3 4 5 6 7 8 9
plannapus
źródło
2

Scala, funkcja 243 bajtów (samodzielna aplikacja 315 bajtów), Mergesort

Ta odpowiedź ma być funkcją, ale może zostać rozszerzona jako samodzielna aplikacja.

Tylko funkcja (243 bajty):

object G{
type S=Stream[Int]
def m(f:(S,S)):S=f match{
case(x#::a,b@(y#::_))if x<=y=>x#::m(a,b)
case(a,y#::b)=>y#::m(a,b)
case(a,Empty)=>a
case(_,b)=>b}
def s(a:S):S=if(a.length>1)((q:S,w:S)=>m(s(q),s(w))).tupled(a.splitAt(a.length/2))else a
}

Aplikacja autonomiczna (315 bajtów):

object G extends App{
type S=Stream[Int]
def m(f:(S,S)):S=f match{
case(x#::a,b@(y#::_))if x<=y=>x#::m(a,b)
case(a,y#::b)=>y#::m(a,b)
case(a,Empty)=>a
case(_,b)=>b}
def s(a:S):S=if(a.length>1)((q:S,w:S)=>m(s(q),s(w))).tupled(a.splitAt(a.length/2))else a
println(s(args(0).split(",").map(_.toInt).toStream).toList)
}

Stosowanie:

Funkcjonować: G.s(List(**[Paste your array here]**).toStream).toList

Podanie: sbt "run **[Paste your array here]**"

Przykładowe dane wejściowe:

scala> G.s(List(10,2,120,1,8,3).toStream).toList

(OR)

$ sbt "run 5423,123,24,563,65,2,3,764"

Wynik:

res1: List [Int] = List (1, 2, 3, 8, 10, 120)

LUB

Lista (2, 3, 24, 65, 123, 563, 764, 5423)

Ograniczenia i uwagi:

  • Wymaga scalaz (bardzo popularnej biblioteki, nieużywanej tutaj do sortowania)
  • Jest w 100% funkcjonalny (nic nie można zmienić!)

Przypisanie:

Ruslan
źródło
2

Galaretka, 29 bajtów, sortuj według scalania

Podobnie jak odpowiedź Python w orlp, ta metoda jest używana list.pop(0)pod maską O(n), ale implementacja jest formalna O(n log n).

ṛð>ṛḢð¡Ḣ;ñ
ç;ȧ?
s2Z߀ç/µL>1µ¡

Wypróbuj tutaj.

Wyjaśnienie

               Define f(x, y):    (merge helper)
                 Implicitly store x in α.
ṛ    ð¡          Replace it with y this many times:
 ð>ṛḢ              (x > y)[0].
       Ḣ         Pop the first element off that list (either x or y).
        ;ñ       Append it to g(x, y).

               Define g(x, y):    (merge)
  ȧ?             If x and y are non-empty:
ç                  Return f(x, y)
                 Else:
 ;                 Return concat(x, y).

               Define main(z):    (merge sort)
       µL>1µ¡    Repeat (len(z) > 1) times:
s2                 Split z in chunks of length two.   [[9, 7], [1, 3], [2, 8]]
  Z                Transpose the resulting array.     [[9, 1, 2], [7, 3, 8]]
   ߀              Apply main() recursively to each.  [[1, 2, 9], [3, 7, 8]]
     ç/            Apply g on these two elements.     [1, 2, 3, 7, 8, 9]
Lynn
źródło
Czy mógłbyś dodać jakieś wyjaśnienie?
Jest wiele do wytłumaczenia :) Zobaczę, czy mogę trochę
Lynn
Kiedy mówisz, że implementacja to O (n log n), ale używa list.pop (0) pod maską, czyli O (n), jestem zdezorientowany. Co masz na myśli?
Mam na myśli dokładnie to, co napisał orlp w swojej odpowiedzi: To nie jest O (n log n), ponieważ .pop(0)jest O (n), czyniąc funkcję scalania O (n ^ 2). Ale jest to dość sztuczne, jak .pop(0)łatwo mogło być O (1).
Lynn
Galaretka jest zaimplementowana w Pythonie i zaimplementowana jako .pop(0).
Lynn
1

Rubinowy, 167 bajtów

Algorytm sortowania scalonego z golfem, który ma najgorszy przypadek O (n log n)

f=->x{m=->a,b{i,j,l,y,z=0,0,[],a.size,b.size
while i<y&&j<z
c=a[i]<b[j]
l<<(c ?a[i]:b[j])
c ?i+=1:j+=1
end
l+=a[i,y]+b[j,z]}
l=x.size
l>1?m[f[x[0,l/2]],f[x[l/2,l]]]:x}

Sprawdź to tutaj!

Aby przetestować, skopiuj i wklej kod do okna, a następnie dodaj puts f[x]na dole, gdzie x jest tablicą z danymi wejściowymi. (Oczywiście upewnij się, że wybrałeś Ruby jako język) Na przykładputs f[[2, 2, 1, 9, 3, 7, 4, 1, 6, 7]]

Wartość tuszu
źródło
Dziękuję Ci za to! Czy możesz pokazać, że to działa?
1
Dodałem link, abyś mógł go przetestować.
Wartość tuszu
1

Rubinowy, 297 bajtów

Scal sortowanie. Kompletny program zamiast funkcji. Wymaga dwóch argumentów w czasie wykonywania: pliku wejściowego i pliku wyjściowego, każdy z jednym elementem w wierszu.

if $0==__FILE__;v=open(ARGV[0]).readlines.map{|e|e.to_i}.map{|e|[e]};v=v.each_slice(2).map{|e|a,b,r=e[0],e[1],[];while true;if(!a)||a.empty?;r+=b;break;end;if(!b)||b.empty?;r+=a;break;end;r<<(a[0]<b[0]?a:b).shift;end;r}while v.size>1;open(ARGV[1],"w"){|f|f.puts(v[0].join("\n"))if !v.empty?};end
jose_castro_arnaud
źródło
Jeśli skróciłoby to twój kod, powinieneś rozważyć dostosowanie go do funkcji, która pobiera tablicę jako dane wejściowe i zwraca posortowaną sekwencję. wygląda na to, że pozbyłbyś się wielu bajtów.
dumny haskeller
Jeśli zamierzasz zachować go jako pełny program zamiast funkcji, czy mogę zasugerować użycie odpowiednio STDIN i STDOUT jako wejścia / wyjścia? $stdin.readlinesjuż jest mniej niż bajty open(ARGV[0]).readlines, to samo z putsnadopen(ARGV[1],"w"){|f|f.puts
Value Ink
2
I takie rzeczy if $0==__FILE__są naprawdę niepotrzebne w golfie kodowym. Możesz także skondensować, zastępując każdą ;z nową linią - to ta sama liczba bajtów i (prawdopodobnie) usuwa przewijanie kodu w poziomie. Polecam również sprawdzenie wskazówek dotyczących gry w golfa w Ruby .
daniero