Biorąc pod uwagę wymiarowy wektor z rzeczywistymi wpisami, znajdź najbliższą permutację wynoszącą w odniesieniu do odległości .
Detale
- Jeśli jest to wygodniejsze, możesz zamiast tego użyć permutacji . Jeśli istnieje wiele najbliższych kombinacji, możesz wyprowadzić dowolną lub alternatywnie wszystkie z nich.
- odległość pomiędzy dwoma wektorami jest zdefiniowana jako
- Jeśli chcesz, możesz założyć, że dane wejściowe składają się wyłącznie z liczb całkowitych.
Przykłady
[0.5 1] -> [1 2], [2 1]
c*[1 1 ... 1] -> any permutation
[1 4 2 6 2] -> [1 4 3 5 2], [1 4 2 5 3]
[1 3 5 4 1] -> [2 3 5 4 1], [1 3 5 4 2]
[7 7 3 2 5 6 4 2] -> [8 7 3 2 5 6 4 1], [8 7 3 1 5 6 4 2], [7 8 3 2 5 6 4 1], [7 8 3 1 5 6 4 2]
[-2 4 5 7 -1 9 3] -> [1 4 5 6 2 7 3], [2 4 5 6 1 7 3], [1 4 5 7 2 6 3], [2 4 5 7 1 6 3]
[0 4 2 10 -1 10 5] -> [1 4 2 6 3 7 5], [1 4 3 6 2 7 5], [2 4 3 6 1 7 5], [3 4 2 6 1 7 5], [1 4 2 7 3 6 5], [1 4 3 7 2 6 5], [2 4 3 7 1 6 5], [3 4 2 7 1 6 5]
Skrypt Octave do generowania większej liczby przykładów.
v
, będą większe niż0
? A przynajmniej nie0
?v
mogą być dowolne liczby całkowite. (Dodano kilka innych przykładów.)[1.6 2]
jest to ważny przypadek testowy (zachłanny algorytm / sortowanie leksykograficzne daje złą odpowiedź).Odpowiedzi:
Python 2 , 60 bajtów
Wypróbuj online!
Wykorzystuje indeksowanie zerowe.
Szybki algorytm z prostym pomysłem. Gdybyśmy zamiast tego trzeba permutacji listę wejściowy, aby go jak najbliżej(1,2,...,n) , jak to możliwe, powinniśmy po prostu rodzaj to, jak udowodniono poniżej. Ponieważ jesteśmy zamiast permutacji (1,2,...,n) , wybieramy permutacji że zamówione w ten sam sposób jak listy wejściowej, jak w moim wyzwaniem Naśladuj uporządkowanie (z wyjątkiem wejścia mogą mieć powtórzeń). (Edycja: mile wskazało na to bardziej identyczne wyzwanie , na które Dennis ma tę samą odpowiedź ).
Należy pamiętać, że tylko własność(1,2,...,n) , które użyliśmy jest to, że sortowane, tak samo algorytm będzie działać do permutacji dowolną listę zminimalizować dystans do dowolnej ustalonej listy.
W kodzie jedynym celem
z=zip(l,range(len(l)))
jest rozróżnienie elementów wejściowych, czyli uniknięcie powiązań, przy jednoczesnym zachowaniu tych samych porównań między nierównymi elementami. Jeśli dane wejściowe gwarantujemy, że nie będziemy powtarzać, możemy to usunąć i po prostu miećlambda l:map(sorted(l).index,l)
.źródło
05AB1E , 7 bajtów
Wypróbuj online!
Wyjaśnienie
źródło
Perl 6 , 44 bajtów
Wypróbuj online!
Anonimowy blok kodu, który zwraca pierwszą minimalną permutację z 0 indeksowaniem.
Wyjaśnienie:
Myślę, że mógłbym również pozbyć się
.sum
i posortować według listy wartości bezwzględnych, ale nie jestem pewien, czy to rzeczywiście jest poprawne, choć przechodzi moje obecne przypadki testowe.źródło
[0.6 1]
(zakładając, że mamy indeks 0), gdzie jeśli zoptymalizujesz dla pierwszej wartości, uzyskasz[1,0]
wynik 1,4, ale jeśli zoptymalizujesz dla całego wektora, 1 jest bardziej wartościowy na drugiej pozycji dla wyniku 0,6.Galaretka , 8 bajtów
Wypróbuj online!
źródło
Galaretka , 5 bajtów
Monadyczny link akceptujący listę liczb, która daje listę liczb całkowitych.
Wypróbuj online! Lub zobacz pakiet testowy .
W jaki sposób?
Uwaga
L
(długość) działałaby zamiastJ
odœ?
podanej liczby całkowitejn
, po prawej domyślnie tworzyłby zakres[1..n]
do pracy, aleJ
jest jawny.źródło
Rubin ,
6360 bajtówWypróbuj online!
Jest tutaj sztuczka matematyczna, która może być pomocna także w innych odpowiedziach - zamiast minimalizować sumę wartości bezwzględnych różnic, maksymalizujemy sumę produktów. Dlaczego to działa?
Minimalizowanie sumy
(x-y) squared
nie jest równoważne z minimalizowaniem sumy|x-y|
, ale zawsze da prawidłową odpowiedź, po prostu priorytetem jest zmniejszenie dużych różnic nad małymi, podczas gdy rzeczywiste wyzwanie jest obojętne między nimi.Ale
(x-y)*(x-y)
=x*x+y*y-2*x*y
. Ponieważ wyrażenia kwadratowe zawsze pojawiają się gdzieś w sumie dla dowolnej permutacji, nie wpływają one na wynik, więc możemy to uprościć-2*x*y
. Te2
czynniki out, więc możemy uprościć do-x*y
. Następnie, jeśli zmienimy minimalizację na maksymalizację, możemy to uprościćx*y
.Intuicyjnie jest to podobne do obserwowania, że jeśli próbujesz zmaksymalizować materiał kwadratowy za pomocą zestawu ścian poziomych i zestawu ścian pionowych, najlepiej sparować ściany o rozmiarach zbliżonych do siebie, aby stworzyć pomieszczenia, które są jak najbliżej kwadratu, jak to możliwe.
3*3 + 4*4 = 25
, podczas gdy3*4 + 4*3 = 24
.Edycja: Zapisano trzy bajty, generując i oceniając ciąg formatu zamiast używać zip i sumy.
źródło
Gaia , 13 bajtów
Wypróbuj online!
źródło
JavaScript (ES6), 61 bajtów
Na podstawie wglądu xnor .
Wypróbuj online!
Skomentował
JavaScript (ES6),
130128 bajtówNie
musi byćna pewno jest bardziej bezpośredni sposób ...0-indeksowane.
Wypróbuj online! (z wyjściem 1-indeksowanym)
W jaki sposób?
Funkcja pomocnikasol oblicza wszystkie permutacje ( 0 , . . . , N - 1 ) , gdzie n jest niejawną długością tablicy wejściowej a [] .
Dla każdej permutacjip obliczamy:
W końcu zwracamy permutację, która prowadzi do najmniejszejk .
źródło
Wolfram Language (Mathematica) , 14 bajtów
Wypróbuj online!
Na podstawie wglądu xnor .
źródło
Python 2 ,
149126112 bajtów-23 bajty dzięki Mr. Xcoder
-14 bajtów dzięki xnor
Wypróbuj online!
Wykorzystuje permutacje (0 ... n-1).
źródło
functools
już więcej nie potrzebował .reduce
jest zwykle przesada, szczególnie tutaj, gdzie dodajesz rzeczy. Myślę, że możesz po prostu zrobićsum(abs(p-q)for p,q in zip(x,a))
.bez żadnego pakietu permutacji
Python 3 , 238 bajtów
Wypróbuj online!
źródło
Wolfram Language (Mathematica) , 57 bajtów
Wypróbuj online!
źródło
Japt
-g
, 12 bajtówSpróbuj
W przypadku indeksowania 0 zamień pierwsze 2 bajty
m,
na, aby zamiast tego zamapować tablicę na jej indeksy.źródło
J ,
258 bajtówWypróbuj online!
Znacznie krótsza odpowiedź oparta na genialnym pomyśle Xnora.
oryginalna odpowiedź
J , 25 bajtów
Wypróbuj online!
źródło