Scal sortowanie
W tym wyzwaniu zaimplementujesz podprogram scalania sortowania scalającego. W szczególności musisz utworzyć funkcję, program, czasownik lub podobny, który pobierze dwie listy, każdą posortowaną w porządku rosnącym, i połączy je w jedną listę posortowaną w kolejności rosnącej. Wymagania:
- Twój algorytm musi zająć asymptotycznie liniowy czas w wielkości danych wejściowych. Przestańcie podawać rozwiązania O (n ^ 2).
- Nie możesz używać żadnych wbudowanych funkcji zdolnych do sortowania listy, scalania listy lub czegokolwiek podobnego. Według uznania autora.
- Kod powinien być w stanie obsłużyć powtarzające się elementy.
- Nie martw się o puste listy.
Przykłady:
merge([1],[0,2,3,4])
[0,1,2,3,4]
merge([1,5,10,17,19],[2,5,9,11,13,20])
[1, 2, 5, 5, 9, 10, 11, 13, 17, 19, 20]
To jest kod-golf , więc może wygrać najkrótszy kod!
b=a;b=b.length
może powielić całą tablicęa
(i dać czas O (n ^ 2), jeśli zostanie wykonany dla każdego elementu) lub powielić tylko odniesienie do czasu tablicy (O (n)). Który się liczy?Odpowiedzi:
Rebmu (
3532 znaków)Test
O
Rebmu jest dialektem Rebola, który pozwala na „musowanie” zwykłego kodu w sytuacjach wymagających zwięzłości. Unmushed, kod działa podobnie jak:
Wierzę, że spełnia to wymóg O (n) , ponieważ blok till jest co najwyżej zapętlony tyle razy, ile długość wejściowa (a
reverse
jedyna zmiana kolejności kontenerów bloków wejściowych, a nie samych bloków). Za pomocątake
jest być może swobodą, ale wciąż stanowi niewielki hit wydajności.Rebol (
8375 znaków)Tylko trochę inaczej: w Rebol ścieżki są krótszym wyrażeniem niż
first
lubsecond
.a
to blok wejściowy zawierający dwa bloki:źródło
Rozwiązania OP:
Haskell
494440Python
1311051019993Dzięki dzięki @Evpok:
źródło
a%b=a++b
po dopasowaniu wzorca głównego, aby obsługiwać puste listy, które golą kilka znaków.Python (79)
Python (95, jeśli nie wolno nam zwrócić generatora)
Itertools to rozwiązanie wszystkich trudnych problemów.
Premia: dwie z nich pracują na dowolnej liczbie list i martwią się o puste listy (jak w tym przypadku, chętnie wezmą 2 puste listy i zwrócą pustą listę, lub wezmą 1 pustą i 1 niepustą listę, i zwrócą niepuste. Kolejna dodana funkcja dwóch niewydanych: będą one również działać bez argumentów i po prostu zwrócą pustą listę).
Nie golfowany:
źródło
r+=[...]
zamiastr.append(...)
(zapisuje 4 znaki za każdym razem)C - 75
Działa to na
NULL
tablicach zakończonychint *
, choć działałoby równie dobrze dla wskaźników do innych typów, zastępując odpowiednią funkcję porównania**b < **a
(npstrcmp(*b, *a) < 0
.).Nie golfowany:
źródło
Golfscript,
2927302926 bajtówlub
Jak to działa
Komenda
będą przetwarzane w następujący sposób:
Dane wyjściowe to:
źródło
[1 1 1 ... 2]
I[1 1 1 ... 3]
), ponieważ porównywanie tablic (a nie ich pierwszych elementów) byłoby w tym przypadku bardzo powolne.J -
4233Zmodyfikowana wersja stąd + komentarz @algorithmshark
k
dołącza nagłówek prawej tablicy do scalonych ogonów obu tablic.k~
jest taki sam, ale z odwróconymi tablicami.(>&{.)
porównuje głowy. Kod zgłosi błąd, jeśli jedna z tablic jest pusta, w takim przypadku zwracamy tylko ich konkatenację,
.źródło
/:~ a,b
jest to odpowiedź zabroniona (wraz z[:/:~,
), że strzelasz do najkrótszej odpowiedzi, która nie zawiera/:
, prawda?m=:k~`k@.(>&{.)`,@.(0=*&#)
oszczędza 2 znakik=:(m}.),~0{]
im=:k~`k@.(>&{.) ::,
. Używamy,0{
aby zgłosić błąd, gdy lista jest pusta, a następnie złapać ten błąd i wyjść z,
.JavaScript (ES6),
6979 bajtówJak to działa
źródło
<
operatorem nie jest prawidłowe, ponieważ dokonuje porównania ciągów:f([123, 456, 789], [1, 2, 3, 4, 5]) => [1, 123, 2, 3, 4, 456, 5, 789]
[]
a następnie konwertowanie jej na ciąg wymaga O (n) czasu. Wykonanie tego raz dla wszystkich n elementów tablicy zajmuje czas O (n ^ 2).Python
(63) (69)(71)Napisałem to, zanim zobaczyłem komentarze OP dotyczące środowisk wykonawczych innych odpowiedzi, więc jest to kolejne rozwiązanie, które O (n) w algorytmie, ale nie implementacja.
źródło
return[a.pop(0)]+(a and m(a,b)or b)
Haskell, 35 bajtów
Haskell, 30 bajtów (niekonkurencyjny)
Ta niekonkurencyjna wersja gwarantuje liniowe działanie tylko wtedy, gdy
a
ib
mają elementy rozłączne; w przeciwnym razie nadal działa poprawnie, ale może zająć kwadratowy czas.źródło
PHP
91 9891 bajtówedycja nr 1: Pusta
$b
wymaga dodatkowego warunku w nawiasach klamrowych (+7).edycja nr 2: drobne gra w golfa
edycja nr 3: dodano drugą wersję
całkiem prosto. Najładniejszą częścią jest trójskładnik wewnątrz
array_shift
(który zawiedzie, jeśli spróbujesz go bez kręconych)
lub
bez golfa
test
źródło
$a&(!$b|$a[0]<$b[0])?$a:$b
zamiast tego nie jest to proste${$a&(!$b|$a[0]<$b[0])?a:b}
array_shift
Parametr jest używany przez odniesienie. To musi być zmienna; wyrażenie nie zadziała.Idź, 124 znaki
źródło
JavaScript - 133
Takie samo podejście jak PO.
źródło
perl, 87 znaków / perl 5.14, 78 + 1 = 79 znaków
Ta implementacja blokuje odwołania do tablic wejściowych. Poza tym jest to dość proste: podczas gdy obie tablice mają coś, przesuń niższą z dwóch. Następnie zwróć scalony bit połączony z pozostałymi bitami (pozostanie tylko jeden z @ $ x lub @ $ y). Prosto perl5, 87 znaków:
Używając perla 5.14.0 i jego nowej zmiany tablicy: 78 znaków + 1 kara kary = 79 znaków:
źródło
*
zamiast&&
zapisuje bajt. A nawet więcej, jeślisub M{map{shift(!@$x+@$y*($$y[0]<$$x[0])?$y:$x)}map@$_,($x,$y)=@_}
Java: 144
To jest całkiem proste. Funkcja, która pobiera dwie tablice i zwraca jedną, wersję scaloną, golfa i bez opakowania kompilacji:
Ungolfed (z opcją kompilacji i uruchamiania):
Przykładowe wykonania:
Wszelkie wskazówki dotyczące skrócenia byłyby mile widziane.
źródło
Scala, 97 bajtów
Rozwiązanie rekurencyjne z O (n). Aby skrócić kod, czasami wykonuje się operację przez zmianę 2 wymiennych parametrów, tj. Wywołań f (a, b) f (b, a).
Nie golfowany:
źródło
APL (32)
Wyjaśnienie:
źródło
LISP, 117 bajtów
Algorytm kończy się
n + 1
iteracjami, gdzien
jest długością najkrótszej listy na wejściu.źródło
PYG (50)
PYG (ponownie 64, jeśli nie są dozwolone żadne generatory.):
Adaptacja mojej odpowiedzi w języku Python .
źródło
Python - 69 bajtów
Gdyby kolejność wejścia i wyjścia była malejąca, można to skrócić do 61 bajtów :
I dalej do 45 bajtów, jeśli dozwolone są generatory:
źródło
pop(0)
mogą być zaimplementowane w O (1) i+=
przynajmniej mogą być zaimplementowane lepiej niż O (n) (patrz link). Nawiasem mówiąc, twoje rozwiązanie używa+=
(tj.append
Iextend
) tak często jak moje. W każdym razie, wszystko to jest pytanie implementacyjne (o ile mi wiadomo), więc w (fikcyjnej) implementacji Pythona, gdzie listy są implementowane jako listy, moją funkcją jest O (n). Wreszcie twoje pytanie wymagało, aby algorytm był O (n), a mój jest.Perl 6: 53 znaków
Przejdź od dowolnej z wartości
a
lubb
ma mniejszą wartość, aża
XORb
(a^b
) będzie prawdziwe. Następnie zwróć wszystko, co pozostało, spłaszczając ([]
) tablice do listy (a[],b[]
).Zakładając, że przesunięcie od początku tablicy wynosi O (n), najgorszym przypadkiem są dwa porównania i jedno przesunięcie na element, więc algorytm to O (n).
źródło
JavaScript (ES5)
908690 bajtówedytować: (90 -> 86) Przeniesiono trójskładnik do warunku pętli for. Pomysł skradziony Dennisowi.
edit: (86 -> 90) Usunięto rzutowanie Array na String, ponieważ łamie wymaganie O (n) .
źródło
Mathematica,
137135Wejście:
Wynik:
Nie golfowany:
Prawdopodobnie może być lepiej.
źródło
m[a:{x___,y_},b:{___,z_}]:=If[y<z,b~m~a,{x}~m~b~Join~{y}];{}~m~b_=b;
R, 80
Takie samo rozwiązanie jak w Scali i innych językach. Nie jestem pewien, czy x [-1] to O (1).
źródło
Mathematica, 104 bajty
Funkcja anonimowe przechowuje długość dwóch listy zmiennych wejściowych
m
in
, wówczas każdy iteracjiDo
pętliSow
s elementem jednej listy zwiększając licznik tej listy (i
w pierwszym,k
w drugim) o jeden. Jeśli jeden z liczników przekroczy długość listy,If
instrukcja zawsze będzieSow
elementem z drugiej listy. Pon+m
operacji zadbano o wszystkie elementy.Reap
a raczej część[[2,1]]
jego danych wyjściowych to lista elementów w kolejności, w jakiej byłySow
n.Nie jestem pewien, czy dane wewnętrzne (uzyskują dostęp do części listy,
O(1)
czy nie), ale czasy na mojej maszynie wyglądały dość liniowo w odniesieniu do długości listy danych wejściowych.źródło