Dyadyczna transpozycja

9

Podobnie jak w przypadku większości symboli APL, ma różne znaczenia, gdy wywoływany jest z jednym argumentem (transpozycja) w porównaniu z dwoma argumentami (wymiary transponowania / zmiany kolejności). To wyzwanie dotyczy tego drugiego, który działa podobnie do numpy.moveaxisPythona lub permuteMATLAB, ale ma większą moc.

order ⍉ Akiedy orderma wyraźne wpisy

Gdy wszyscy członkowie ordersą odrębni, order ⍉ Ajest to równoważne z:

  • numpy.moveaxis(A, tuple(range(len(A.shape)), order) w Pythonie lub
  • permute(A,order)w MATLAB. Cytowanie z dokumentacji tego ostatniego:

B = permute (A, kolejność) przestawia wymiary A, tak aby były w kolejności określonej przez kolejność wektorów. Wynikowa tablica B ma takie same wartości jak A, ale kolejność indeksów dolnych potrzebnych do uzyskania dostępu do dowolnego konkretnego elementu jest zmieniana zgodnie z kolejnością.

Załóżmy na przykład, że Ajest to tablica 3D i let B ← (2 0 1)⍉A. Zatem B jest takie, że B[x0,x1,x2] = A[x2,x0,x1]dla wszystkichx2,x0,x1

order ⍉ Akiedy orderpowtórzył wpisy

Po orderpowtórzeniu wpisów bierzemy przekątną tablicę. Na przykład niech A będzie tablicą 2x3x4. B ← (0 0 1)⍉Abierze ukośny kawałek, Aaby utworzyć Btaki B[x0,x1] = A[x0,x0,x1]. Zauważ, że Bjest to tablica 2x4: gdyby była to 3x4, musielibyśmy ustawić, B[2, x1] = A[2, 2, x1]która byłaby poza zakresem A. Ogólnie rzecz biorąc, ten kwymiar Bbędzie minimum wszystkich A.shape[i]takich, które order[i] = k.

Przykład

Rozważmy transpozycję dyadyczną order⍉Agdzie order = [2, 1, 0]i A to 3x4x5

    A =
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]
  [10 11 12 13 14]
  [15 16 17 18 19]]

 [[20 21 22 23 24]
  [25 26 27 28 29]
  [30 31 32 33 34]
  [35 36 37 38 39]]

 [[40 41 42 43 44]
  [45 46 47 48 49]
  [50 51 52 53 54]
  [55 56 57 58 59]]]

Wynikiem jest tablica 5x4x3 B =

[[[ 0 20 40]
  [ 5 25 45]
  [10 30 50]
  [15 35 55]]

 [[ 1 21 41]
  [ 6 26 46]
  [11 31 51]
  [16 36 56]]

 [[ 2 22 42]
  [ 7 27 47]
  [12 32 52]
  [17 37 57]]

 [[ 3 23 43]
  [ 8 28 48]
  [13 33 53]
  [18 38 58]]

 [[ 4 24 44]
  [ 9 29 49]
  [14 34 54]
  [19 39 59]]]

Zauważ, że gdy np. (X0, x1, x2) = (4,1,2) mamy B[x0,x1,x2] = A[x2, x1, x0] = A[2,1,4] = 49.

Jeśli zamiast tego order = [0, 0, 0]i Ajak wyżej, otrzymalibyśmy wynik Bw postaci 1-wymiarowej tablicy rozmiar-3, B = [0, 26, 52]aby takB[1] = B[x0] = A[x0,x0,x0] = A[1,1,1] = 26

Wejście

W tym przypadku korzystamy z indeksowania 0, ale można również stosować indeksowanie 1, tak jak domyślna wartość APL.

  • Wielowymiarowa lub zagnieżdżona tablica Ao wymiarze n ≥ 1.

  • Lista orderz n dodatnich liczb całkowitych, składająca się z liczb całkowitych {0,1, ..., K} (i {1, ..., k + 1} 1-index) dla niektórych k < n , w dowolnej kolejności, ewentualnie z powtórzeniami.

Wynik

  • Wielowymiarowa lub zagnieżdżona tablica reprezentująca wynik zastosowania transpozycji dyadycznej z tymi argumentami. (Dane wyjściowe będą miały wymiar k + 1 ).

Możesz napisać pełny program, funkcję itp., Zgodnie z obowiązującym standardem na meta.

Jeśli Twój język ma wbudowaną wersję, zachęcamy do napisania rozwiązania bez wbudowanej wersji w celu uzyskania interesującej odpowiedzi.

Przypadki testowe

Przypadki testowe na TIO

Dokumentacja implementacji języka Python już wkrótce.

Uwaga do czytania przypadków testowych: w APL przedostatnia i ostateczna oś tablicy są wzdłuż kolumn i wierszy w tej kolejności.

lirtosiast
źródło
4
APL, 1 bajt:: P
Quintec,
1
W rzeczywistości wiele symboli APL używa domyślnego drugiego argumentu, gdy wywoływany jest z jednym argumentem. Obejmuje to, które domyślnie wykorzystuje indeksy odwróconej osi, więc ⍉Ajest to to samo, co (2 1 0)⍉Ajeśli Ajest trójwymiarową tablicą i ogólnie ⍉Ajest (⌽⍳≢⍴A)⍉A.
Adám
@lirtosiast pytanie o we / wy: czy tablica wielowymiarowa może być reprezentowana jako para kształtu (lista wymiarów) i treści (wszystkie elementy w porządku leksykograficznym ich indeksów)?
ngn
@ngn Powiedziałbym na razie nie, ale powinieneś zapytać na meta, czy ten format jest domyślnie akceptowany.
lirtosiast
@lirtosiast Anecdotally, Dyalog APL wewnętrznie przechowuje tablice jako [number-of-dimensions,first-dimension-length,second-dimension-length,…,last-dimension-length,first-element,second-element,…,last-element].
Adám,

Odpowiedzi:

4

APL (Dyalog Unicode) , 34 bajty SBCS

To jest kod mojego kolegi (nieco zmodyfikowany z Rogera Hui : Historia APL w 50 funkcjach , rozdział 30 ), opublikowany za wyraźną zgodą.

Anonimowa milcząca infix lambda (może być używana jako drop-in dla ).

{⍵[(⊂⊂⍺)⌷¨,¨⍳⍺[⍋⍺]{⌊/⍵}⌸(⍴⍵)[⍋⍺]]}

Wypróbuj online!

{} Dfn;jest lewym argumentem (osie), jest prawym argumentem (tablica)
Np. [2,2,1]i[[[1,2],[3,4]]]

⍵[] Indeksuj tablicę za pomocą:

  (⍴⍵)[]  Kształt (długości osi) tablicy, indeksowany według:
  [1,2,2]

   ⍋⍺ wektor gradacji (wskaźniki, które by je posortowały) osi
   [3,1,2]
  [2,1,2]

  ⍺[⍋⍺]{}⌸ Użyj posortowanych osi jako kluczy do grupowania tego i dla każdej grupy:
  [1,2,2]{"1":[2],"2":[1,2]}

   {⌊/⍵} znajdź najniższą długość osi
   {"1":2,"2":1}[2,1]

   generować wskaźniki w układzie kartezjańskim o tych wymiarach
  [[[1,1]],[[2,1]]]

   upewnij się, że indeksy każdej współrzędnej są wektorem (byłoby skalarne, jeśli jest wektorem)
  [[[1,1]],[[2,1]]]

  ()⌷¨ Indeksuj do każdego z następujących elementów:

   ⊂⊂⍺ osie (podwójnie zamknięte; raz, aby wybrać te komórki wzdłuż pierwszej i jedynej osi, i raz, ¨aby sparować każdy wektor po prawej stronie z całym zestawem osi po lewej)
   2 1 2
  [[[1,1,1]],[[1,2,1]]]
[[1],[3]]

Adám
źródło