Powinienem posortować listę liczb, ale jestem bardzo leniwy. Naprawdę trudno jest wymyślić, jak zamieniać wszystkie liczby, dopóki wszystkie nie będą rosły w porządku, więc wymyśliłem własny algorytm, który zagwarantuje, że nowa lista zostanie posortowana¹. Oto jak to działa:
Aby uzyskać listę rozmiarów N , potrzebujemy iteracji N-1 . Przy każdej iteracji
Sprawdź, czy N-ty numer jest mniejszy niż N + 1-ty numer. Jeśli tak, to te dwie liczby są już posortowane i możemy pominąć tę iterację.
Jeśli nie są, musisz ciągle zmniejszać pierwsze N liczb, aż te dwie liczby będą w porządku.
Weźmy konkretny przykład. Powiedzmy, że dane wejściowe były
10 5 7 6 1
Przy pierwszej iteracji porównamy 10 i 5. 10 jest większe niż 5, więc zmniejszamy go, aż będzie mniejszy:
4 5 7 6 1
Teraz porównujemy 5 i 7. 5 jest mniejsze niż 7, więc nie musimy nic robić w tej iteracji. Przechodzimy więc do następnego i porównujemy 7 i 6. 7 jest większe niż 6, więc zmniejszamy pierwsze trzy liczby, aż będą mniejsze niż 6, i otrzymujemy:
2 3 5 6 1
Teraz porównujemy 6 i 1. Ponownie, 6 jest większe niż 1, więc zmniejszamy pierwsze cztery liczby, aż będą mniejsze niż 1, i otrzymujemy:
-4 -3 -1 0 1
I skończone! Teraz nasza lista jest w idealnym porządku posortowanym. A żeby było jeszcze lepiej, musieliśmy tylko iterować listę N-1 razy, więc ten algorytm sortuje listy w czasie O (N-1) , co, jestem pewien, jest najszybszym dostępnym algorytmem.
Twoim dzisiejszym wyzwaniem jest wdrożenie tego Lazy Sort. Twój program lub funkcja otrzyma tablicę liczb całkowitych w dowolnym standardowym formacie, który ci się podoba, i musisz wykonać to leniwe sortowanie i zwrócić nową listę „posortowaną” . Tablica nigdy nie będzie pusta ani nie będzie zawierać liczb całkowitych.
Oto kilka przykładów:
Input: 10 5 7 6 1
Output: -4 -3 -1 0 1
Input: 3 2 1
Output: -1 0 1
Input: 1 2 3
Output: 1 2 3
Input: 19
Output: 19
Input: 1 1 1 1 1 1 1 1 1
Output: -7 -6 -5 -4 -3 -2 -1 0 1
Input: 5 7 11 6 16 2 9 16 6 16
Output: -27 -25 -21 -20 -10 -9 -2 5 6 16
Input: -8 17 9 7
Output: -20 5 6 7
Jak zawsze jest to golf kodowy , więc napisz najkrótszy program, jaki możesz!
¹ To nie znaczy, jak to brzmi, ale jest technicznie prawdą
² Żartuję całkowicie, proszę, nie nienawidź mnie
źródło
<sarcasm>
Ten algorytm sortowania w rzeczywistości wciąż mierzyO(N^2)
złożoność czasową, ponieważ musisz przejrzeć wszystkie wcześniej dostępne elementy na liście, aby je zmniejszyć. Zamiast tego polecam przewinięcie listy do tyłu i, w razie potrzeby, zmniejszanie tylko jednej liczby na krok. To zapewni Ci prawdziwąO(N)
złożoność!</sarcasm>
O(n^2)
pod względem dostępu do pamięci, ale czy nie jest toO(n)
dla porównań?O(N^2)
.Odpowiedzi:
Galaretka ,
14 12 119 bajtów-2 bajty dzięki produktom ETH (użyj minimalnej dyady
«
)Monadyczny link pobierający i zwracający listy liczb całkowitych.
Wypróbuj online! lub zobacz pakiet testowy .
Naprawdę nie sądzę, że to wystarczy Lazy ™!
W jaki sposób?
źródło
Haskell , 40 bajtów
Wypróbuj online!
źródło
JavaScript (ES6), 61 bajtów
Przypadki testowe
Pokaż fragment kodu
źródło
Galaretka , 12 bajtów
Wypróbuj online!
Jak to działa
Podstawowa idea w grze jest następująca: jeśli odwrócisz tablice wejściowe i wyjściowe, dane wyjściowe to po prostu dane wejściowe z każdą deltą 0 lub większą zastąpioną przez -1. Na przykład:
źródło
k, 20 bajtów
Wypróbuj online.
Wyjaśnienie:
źródło
Haskell, 56 bajtów
Wypróbuj online!
Zachowaj pierwszą część listy w parametrze
a
. Na każdym kroku dodaj następny elementx
na końcua
i zwiększ wszystkie elementy o minimum o(y-x-1)
i0
.źródło
Python , 54 bajty
Wypróbuj online!
Pobiera dane wejściowe jak
f(1,2,3)
. Wyświetla listę. Wykorzystuje czas wykładniczy.źródło
C #, 76 bajtów
To modyfikuje listę na miejscu. Przewija listę do tyłu i zachowuje bieżącą sumę delty, aby zastosować ją do każdej liczby.
źródło
JavaScript (ES6), 59 bajtów
źródło
f=
odpowiedzi JS, aby zaoszczędzić dwa bajtyf(a)
), więc nadal wymaga nazwy.Brain-Flak , 153 bajty
Wypróbuj online!
Dotyczy to
+1
również-r
flagi.źródło
R, 56 bajtów
function(s){s-c(rev(cumsum(rev(pmax(0,-diff(s)+1)))),0)}
źródło
diff
, próbowałem wymyślić, jak to zrobić ... Nawiasem mówiąc, możesz pozbyć się nawiasów klamrowych wokół ciała funkcji na -2 bajty, ale jeszcze lepiej, możesz użyćs=scan()
zamiast funkcji definicja, aby zapisać jeszcze kilka bajtów. Byłoby wspaniale, gdybyś zamieścił link Wypróbuj online , aby inne osoby mogły sprawdzić, czy ten kod działa we wszystkich przypadkach testowych.JavaScript (ES6), 68 bajtów
Wejście i wyjście to tablica liczb całkowitych.
Test Snippet
źródło
JavaScript (ES6), 50 bajtów
Wyjaśnienie:
Jest to rozwiązanie rekurencyjne, które najpierw klonuje tablicę, a następnie zmniejsza wszystkie wartości, aż element będzie większy lub równy następnemu elementowi w tablicy.
Funkcja wywołuje się, dopóki dowolne elementy nie działają. Kiedy elementy zostaną ostatecznie posortowane, klon jest zwracany. (Nie możemy zwrócić samej tablicy, ponieważ
some()
metoda obniżyłaby wszystkie jej elementy, powodując ich wyłączenie o -1).Przypadki testowe:
źródło
SWI-Prolog, 194 bajty
Może być w stanie spróbować online tutaj: http://swish.swi-prolog.org/p/LazySort.pl
Pytasz,
l(L, [10,5,7,6,1]).
co mówi „rozwiąż dla L, gdzie L jest leniwą posortowaną wersją tej listy”.Dwie funkcje to:
l
azysorted (A, B) - stwierdza, że A jest leniwą wersją B, jeśli oba są pustymi listami, lub jeśli A można uzyskać poprzez odwrócenie B, wywołanie funkcji pomocnika, aby przejść listę i wykonać odejmowanie za pomocą akumulatora popychając każdą wartość niższą niż poprzednia i odwracając jej wynik z powrotem na właściwy sposób.f
pomocnik dopasowuje dwie listy, wartość poprzedniego numeru na liście i akumulator różnicy ruchomej, i rozwiązuje dla nowej wartości bieżącej pozycji listy wartość oryginalną minus akumulator różnicowy, opcjonalnie minus nową wartość wymaganą do wymuszenia tego wartość poniżej poprzedniego numeru na liście if
musi rozwiązać rekurencyjnie dla końca listy z akumulatorem o teraz zwiększonej różnicy.Zrzut ekranu przypadków testowych na Swish:
źródło
JavaScript (ES6), 61 bajtów
Nie jest to najkrótsze rozwiązanie, ale nie mogłem pominąć okazji do użycia
reduceRight
.źródło
C # (.NET Core) ,
89 88 8679 bajtówfor
s.Wypróbuj online!
Najpierw
for
iteruje przez tablicę, następnie oblicza zmniejszenie, a na koniec drugiefor
zmniejsza elementy, jeśli to konieczne, aż doi
pozycji th.Czy wystarczy zmodyfikować oryginalną tablicę zamiast zwracać nową (wciąż przyzwyczajając się do reguł)?
źródło