Wprowadzenie
Permutacje leksykograficzne listy zawierającej n elementów mogą być ponumerowane od 0 do n ! - 1. Na przykład 3! = 6 permutacji (1,2,3)
byłoby (1,2,3)
, (1,3,2)
, (2,1,3)
,(2,3,1)
, (3,1,2)
, (3,2,1)
.
Po zastosowaniu permutacji do listy jej elementy są uporządkowane w tej samej kolejności, co liczby w permutacji. Na przykład zastosowanie permutacji (2,3,1)
dol = (a,b,c)
wydajności (l[2],l[3],l[1]) = (b,c,a)
.
Odwrotność permutacji jest definiowana jako permutacja, która odwraca tę operację, tj. Zastosowanie permutacji, a następnie jej odwrotność (lub odwrotnie) nie modyfikuje tablicy. Na przykład odwrotność (2,3,1)
jest (3,1,2)
, ponieważ stosuje się to do (b,c,a)
zbiorów (a,b,c)
.
Również odwrotność permutacji zastosowana do samej permutacji daje liczby całkowite 1… n . Na przykład zastosowanie (3,1,2)
do (2,3,1)
plonów (1,2,3)
.
Definiujemy teraz funkcję revind ( x ) jako indeks odwrotnej permutacji permutacji o indeksie x . (To jest A056019 , jeśli jesteś zainteresowany.)
Ponieważ permutacja z indeksem i modyfikuje tylko ostatnie k elementów listy iff 0 ≤ i < k !, Możemy dodać dowolną liczbę elementów na początku listy bez wpływu na revind ( i ). Dlatego długość listy nie wpływa na wynik.
Wyzwanie
Twoim zadaniem jest zaimplementowanie revind ( x ). Napiszemy pełny program lub funkcję, która przyjmuje jedną nieujemną liczbę całkowitą x jako dane wejściowe / argument i wyprowadza / zwraca wynik jako jedną nieujemną liczbę całkowitą.
Dane wejściowe i wyjściowe mogą być indeksowane 0 lub indeksowane 1, ale musi to być spójne między nimi.
Wbudowane, które generują permutacje według indeksu, zwracają indeks permutacji lub znajdują odwrotną permutację, są zakazane. (Wbudowane, które generują wszystkie permutacje lub następne permutacje są dozwolone.)
Standardowy golf zasady .
Przykłady
Poniższe przykłady są indeksowane według 0.
Input Output
0 0
1 1
2 2
3 4
4 3
5 5
6 6
13 10
42 51
100 41
1000 3628
2000 3974
10000 30593
100000 303016
Implementacja referencyjna (Python 3)
def revind(n):
from math import factorial
from itertools import permutations, count
l = next(filter(lambda x: factorial(x) > n, count(1)))
pms = list(permutations(range(l)))
return [k for k in range(len(pms)) if tuple(pms[n][i] for i in pms[k]) == pms[0]][0]
źródło
(a,b,c)
wyjątkowo niejasny. Proszę załączyć właściwe wyjaśnienie, czym jest odwrotna permutacja.Ụ
(stopień w górę), który sortuje indeksy tablicy według odpowiadających im wartości. To dzieje się odwrócić permutacji 1, ..., n , ale to nie działa dla innych permutacji. CzyỤ
zabronione jest wbudowane?Odpowiedzi:
Galaretka , 6 bajtów
We / wy używa indeksowania 1. Bardzo wolny i głodny pamięci.
Weryfikacja
Dopóki dane wejściowe nie przekraczają 8! = 40320 , wystarczy wziąć pod uwagę wszystkie permutacje tablicy [1,…, 8] . W ostatnim przypadku testowym permutacje [1,…, 9] wystarczają .
Z nieco zmodyfikowanym kodem, który uwzględnia tylko permutacje pierwszych 8 lub 9 dodatnich liczb całkowitych, możesz wypróbować online! lub sprawdź wszystkie pozostałe przypadki testowe .
Jak to działa
Alternatywne podejście, 6 bajtów (nieprawidłowe)
Jest tak samo długi i wykorzystuje zakazany atom podwyższenia klasy
Ụ
, ale jest (prawdopodobnie) bardziej idiomatyczny.Przygotowując 8 (lub 9 dla ostatniego przypadku testowego), możemy faktycznie wypróbować online!
Jak to działa
źródło
Mathematica, 74 bajty
Wykorzystuje indeksowanie 1. Bardzo nieefektywne. (zużywa ~ 11 GB pamięci, gdy wejście jest
11
)Wyjaśnienie
Wygeneruj listę od 1 do N. Przechowuj w
j
.Znajdź wszystkie permutacje z
j
. Przechowuj to wi
.Zapisz
Position
funkcję wk
. (aby zmniejszyć liczbę bajtów przyPosition
ponownym użyciu )Znajdź odwrotną permutację N-tej permutacji.
Znajdź
k
(Position
) odwrotnej permutacji wi
(wszystkie permutacje)Korzystanie z wbudowanych
4643 bajtów1-indeksowany.
źródło
MATL , 15 bajtów
Wejścia i wyjścia są oparte na 1.
Podobne do odpowiedzi CJam @ MartinEnder , ale odnajduje odwrotną permutację, komponując wszystkie możliwe permutacje z określonymi przez dane wejściowe i sprawdzając, która stała się permutacją tożsamości.
W kompilatorze online zabrakło pamięci na dane wejściowe
10
.Wypróbuj online!
Wyjaśnienie
źródło
Pyth, 12 bajtów
Zestaw testowy
0 zindeksowanych.
Wyjaśnienie:
źródło
05AB1E ,
1413 bajtówBardzo nieefektywna pamięć.Teraz jeszcze bardziej nieefektywna pamięć (ale o 1 bajt krótsza).Zakres 0.
Wykorzystuje kodowanie CP-1252 .
Wypróbuj online! lub jako zmodyfikowany pakiet testowy
Wyjaśnienie
źródło
CJam , 16 bajtów
Indeksy są oparte na 0.
Wypróbuj online!
Nie wydaję się o wiele bardziej nieefektywny niż to ... brakuje pamięci przy domyślnych ustawieniach Javy dla danych wejściowych większych niż
8
(ale działa w zasadzie dla dowolnych danych wejściowych, biorąc pod uwagę wystarczającą liczbę wszechświatów czasu i pamięci).Wyjaśnienie
źródło
GAP , 108 bajtów
1-indeksowany. Nowe linie nie są liczone, nie są potrzebne. Tak naprawdę nie muszę przypisywać końcowej funkcji do nazwy, ale ...
h
jest funkcją curry, która pobiera listę permutacji i indeks do tej listy i zwraca indeks odwrotnej permuacji. Po prostu bym to zrobiłPosition(l,l[n]^-1)
.f
wywołuje tę funkcję z posortowanymi permutacjami odpowiednio dużej grupy symetrycznej i podanąn
.Mógłbym tylko napisać
SymmetricGroup(n)
, a następnie funkcję można obliczyć dla wartości do 9. Ponieważ istnieją już znacznie mniejsze rozwiązania, wolę móc to zrobić:Naprawdę skuteczne rozwiązanie z indeksowaniem 0, które działa dla argumentów poniżej 99! (i może sprawić, że będzie działał dla argumentów poniżej 999! kosztem jednego bajtu) jest następujący:
Po usunięciu białych znaków ma 255 bajtów.
źródło
JavaScript (ES6),
163120110 bajtów0-indeksowane. Działa poprzez konwersję indeksu na permutację, odwrócenie go, a następnie konwersję z powrotem do indeksu. Edycja: Zapisano około 25%, dokonując
f
odwrócenia i odwrócenia permutacji, a następnieg
przekształcając odwróconą permutację z powrotem w indeks. Zapisano kolejne 10 bajtów, łącząc dwa wywołania rekurencyjne w jedną funkcję. Nie golfowany:źródło
f
permutację zamiastg
...JOT,
5550 bajtówNa podstawie eseju dotyczącego indeksu permutacji .
Ten kod wymaga tylko pamięci w kolejności,
n
ale zużywa więcej czasu, ponieważ sortuje listęn
czasy i wyszukuje jen
dla każdego indeksu.Korzystając z wbudowanego narzędzia,
/:
które potrafi znaleźć ocenę listy i odwrotność permutacji, istnieje 42-bajtowe rozwiązanie, które jest bardziej wydajne.Ta wersja wymaga tylko 44 sekund na obliczenie ostatniego przypadku testowego w porównaniu z drugim, który wymaga 105 sekund.
Stosowanie
źródło
Galaretka ,
14 139 bajtów-4 bajty dzięki @Dennis (którą grałem dalej Korzystanie z szybkiego
⁺
na jego odpowiedź )Kolejna bardzo powolna implementacja.
Zastosowano tutaj indeksowanie 1, więc oczekiwane wyniki to:
Nie ma sensu nawet umieszczać internetowego łącza IDE, ponieważ TIO zabija na wejściu
10
. Wyniki lokalne (ostatnie jest bardzo wolne i wymaga tony pamięci!):W jaki sposób?
Uwaga: nie trzeba sortować permutacji, ponieważ używamy tej samej kolejności zarówno dla znalezienia permutacji, jak i odwrotnie.
źródło
ÇịịÇ$iR
?R
wcześniejŒ!
jest niejawne, więcŒ!ịịŒ!$iR
powinno wykonać zadanie.Python 2,
116114 bajtówrepl.it
W oparciu o 0. Powolny i głodny pamięci, ale mało bajtów.
Bez użycia funkcji permutacji; oszczędność pamięci i czasu.
289285 bajtów-4 bajty dzięki @Christian Sievers (już utworzono pełną permutację)
Wiem, że to jest golf golfowy, ale myślę, że @ Pietu1998 jest również zainteresowany wydajnymi implementacjami.
Zobacz to w akcji na repl.it
Chociaż wykorzystuje to więcej bajtów niż implementacja referencyjna w porównaniu do
n=5000000
:f
jest funkcją wstecznego indeksu.f
Pierwszy dostaje następny silnia powyżejn
,t
oraz liczbę całkowitą, której silnia czylix
dzwoniąch(n)
i zestawówg=range(x)
, elementy, które składają się na permutacji,o=g[:]
i posiadacz permutacji,r=[]
Następnie konstruuje permutację przy indeksie
n
,pop
wprowadzając indeksy reprezentacji podstawy silni zn
kolei z elementówo
i dołączając je dor
. Reprezentacja silnia podstawowa jest określana przez div i modn
zt
gdziet
div jest przezx
ix
zmniejsza się do1
.Wreszcie znajduje indeks odwrotnej permutacji, wywołując
i
odwrotną permutację,[r.index(v)for v in g]
h
jest funkcją podwójnego zastosowania do obliczania silni nieujemnej liczby całkowitej lub do obliczania zarówno następnego silnia powyżej nieujemnej liczby całkowitej, jak i liczby całkowitej, która czyni tę silnię.W stanie domyślnym
v=1
robi to drugie, mnożącv
przezx
(również początkowo1
) i zwiększając,x
ażn
będzie co najmniej tak duży, a następnie zwracav
ix-1
krotce.Aby obliczyć
n!
jedno połączenie,h(n,0)
które się zwielokrotniax
(początkowo1
), których autorem jestn
i zmniejszan
ażn
jest0
, kiedy wracax
.i
zapewnia indeks leksykograficzny permutacjip
przedmiotów[0,1,...n]
poprzez dodanie produktów z silni silni podstawy każdego indeksu,h(len(p)-j-1,0)
i jak wiele elementów po prawej stronie wskaźnika jest mniejsza niż wartość w tym indeksiesum(k<p[j]for k in p[j+1:])
.źródło
t/=x
.(r+o)
przezr
.Python 2,
130129 bajtówźródło
Faktycznie ,
1811 bajtówTa odpowiedź korzysta z algorytmu zawartego w odpowiedzi Dennisa „Jelly”, ale ma indeks 0. Zapraszamy do gry w golfa! Wypróbuj online!
Ungolfing
źródło