Skład grupy dwuściennej D4 z niestandardowymi etykietami

14

Grupa dwuścienna D4 jest grupą symetrii kwadratu, to znaczy ruchami, które przekształcają kwadrat w siebie poprzez obroty i odbicia. Składa się z 8 elementów: obrotu o 0, 90, 180 i 270 stopni oraz odbić w poprzek osi poziomej, pionowej i dwóch przekątnych.

8 elementów D4 działających na kwadracie.

Wszystkie zdjęcia pochodzą z tej uroczej strony autorstwa Larry Riddle'a.

Wyzwanie polega na skomponowaniu tych ruchów: biorąc pod uwagę dwa ruchy, wygeneruj ruch, który jest równoważny z wykonaniem ich jeden po drugim. Na przykład wykonanie ruchu 7, po którym następuje ruch 4, jest tym samym, co wykonanie ruchu 5.

Przykład składu

Zauważ, że zmiana kolejności na ruch 4, a następnie ruch 7 powoduje ruch 6.

Wyniki zestawiono w tabeli poniżej; to jest stół Cayleya grupy D4 . Na przykład dane wejściowe 7,4 powinny dawać wynik 5 .

12345678123456781234567823418756341265874123786557681324685731427685421385762431

Wyzwanie

Twoim celem jest wdrożenie tej operacji w jak najmniejszej liczbie bajtów, ale oprócz kodu wybierasz także etykiety reprezentujące ruchy od 1 do 8. Etykiety muszą mieć 8 różnych liczb od 0 do 255 , lub 8 -bajtowe znaki, które reprezentują ich punkty kodowe.

Twój kod otrzyma dwie etykiety z 8, które wybrałeś i musi wypisać etykietę odpowiadającą ich składowi w dwuściennej grupie D4 .

Przykład

Powiedzmy, że wybrałeś znaki C, O, M, P, U, T, E, R odpowiednio dla ruchów od 1 do 8. Następnie kod powinien implementować tę tabelę.

COMPUTERCOMPUTERCOMPUTEROMPCREUTMPCOTUREPCOMERTUUETRCMOPTRUEMCPOETRUPOCMRUETOPMC

Biorąc pod uwagę wejścia E i P, powinieneś wypisać U. Twoje dane wejściowe będą zawsze składały się z dwóch liter C, O, M, P, U, T, E, R, a twoja informacja wyjściowa powinna zawsze być jedną z tych liter.

Tabela tekstowa do kopiowania

1 2 3 4 5 6 7 8
2 3 4 1 8 7 5 6
3 4 1 2 6 5 8 7
4 1 2 3 7 8 6 5
5 7 6 8 1 3 2 4
6 8 5 7 3 1 4 2
7 6 8 5 4 2 1 3
8 5 7 6 2 4 3 1
xnor
źródło
Your choice of labels doesn't count against your code length.opracowywanie myśli? W tej chwili mogę na stałe zakodować matrycę w moim kodzie i twierdzić, że nie liczy się ona do mojego wyniku.
Benjamin Urquhart
2
@BenjaminUrquhart Próbowałem powiedzieć, że długość twojego kodu jest tylko długością twojego kodu, i powiedzmy, że wybranie etykiet z wieloma cyframi nic nie kosztuje. Wygląda na to, że ta linia jest bardziej myląca niż pomocna, więc ją usunę.
xnor

Odpowiedzi:

10

Rubinowy , 18 bajtów

->a,b{a+b*~0**a&7}

Nie golfił

->a,b{ (a+b*(-1)**a) % 8}  
# for operator precedence reasons, 
#-1 is represented as ~0 in the golfed version 

Wypróbuj online!

Wykorzystuje następujące numery kodowe od 0 do 7

Aby natywny dla kodu:

Native     Effect                    Codes per
Code                                 Question
0          rotate 0 anticlockwise    1C
1 /        flip in y=x               7E
2 /|       rotate 90 anticlockwise   2O
3 /|/      flip in x axis            5U
4 /|/|     rotate 180 anticlockwise  3M
5 /|/|/    flip in y=-x              8R
6 /|/|/|   rotate 270 anticlockwise  4P
7 /|/|/|/  flip in y axis            6T

W porządku według pytania

Native     Effect                    Codes per
Code                                 Question
0          rotate 0 anticlockwise    1C
2 /|       rotate 90 anticlockwise   2O
4 /|/|     rotate 180 anticlockwise  3M
6 /|/|/|   rotate 270 anticlockwise  4P
3 /|/      flip in x axis            5U
7 /|/|/|/  flip in y axis            6T
1 /        flip in y=x               7E
5 /|/|/    flip in y=-x              8R

Wyjaśnienie

/reprezentuje przewrót w linii y=xi |reprezentuje przewrót w osi y.

Jest to możliwe, w celu wytworzenia dowolnego symetrii grupy D4 naprzemian odbijania w tych dwóch liniach, na przykład /, a następnie |daje /|który jest obrót o 90 stopni w kierunku przeciwnym.

Całkowita liczba kolejnych rzutów daje bardzo dogodną reprezentację do manipulacji arytmetycznych.

Jeśli pierwszym ruchem jest obrót, możemy po prostu dodać liczbę przewrotów:

Rotate 90 degrees   +  Rotate 180 degrees = Rotate 270 degrees
/|                     /|/|                 /|/|/|

Rotate 90 degress   +  Flip in y=x        = Flip in x axis   
/|                    /                     /|/

Jeśli pierwszy ruch jest odbiciem, okaże się, że mamy identyczne odbicia /i |symbole obok siebie. Ponieważ odbicie jest odwrotne do siebie, możemy anulować te przerzuty jeden po drugim. Musimy więc odjąć jeden ruch od drugiego

Flip in x axis     +  Flip in y=x        = Rotate 90 degrees
/|/                   /                    /|/ / (cancels to) /|

Flip in x axis     +  Rotate 90 degrees  = Flip in y=x
/|/                   /|                   /|/ /| (cancels to ) / 
Level River St
źródło
1
Możesz zamienić na ~0z 7powodu arytmetyki modułowej.
NieDzejkob
Świetna metoda i wyjaśnienie! Sposób anulowania przerzucania wyjaśnia, dlaczego etykiety dodają lub odejmują.
xnor
7

Wolfram Language (Mathematica) , 31 bajtów

Używając liczb całkowitych 0,5,2),7,1,3),6,4 jako etykiet.

BitXor[##,2Mod[#,2]⌊#2/4⌋]&

Wypróbuj online!

Wyjaśnienie:

Grupa Dihedral re4 jest izomorficzny w unitriangular grupy matrycy na trzecim stopniu polafa2) :

re4U(3),2)): ={(1zab01do001)za,b,dofa2)}.

I mamy

(1za1b101do1001)(1za2)b2)01do2)001)=(1za1+za2)b1+b2)+za1do2)01do1+do2)001),

które można łatwo zapisać w operacjach bitowych.

alephalpha
źródło
Ładna pochodna - nie wiedziałam o tym izomorfizmie.
xnor
5

Wolfram Language (Mathematica) , 51 bajtów

⌊#/4^IntegerDigits[#2,4,4]⌋~Mod~4~FromDigits~4&

Wypróbuj online!

Korzystanie z etykiet {228, 57, 78, 147, 27, 177, 198, 108}.

{3210, 0321, 1032, 2103, 0123, 2301, 3012, 1230}w bazie 4. Na szczęście 256 = 4 ^ 4.


Implementacja niższego poziomu, również 51 bajtów

Sum[4^i⌊#/4^⌊#2/4^i⌋~Mod~4⌋~Mod~4,{i,0,3}]&

Wypróbuj online!

attinat
źródło
4

Python 2 , 22 bajty

0,6,1,7,2),3),5,4 jako etykiety.

lambda a,b:a^b^a/2&b/4

Wypróbuj online!

alephalpha
źródło
4

Python 2 , 26 23 21 bajtów

lambda x,y:y+x*7**y&7

Wypróbuj online! Port mojej odpowiedzi dla Cayley Table of the Dihedral Groupre3). Edycja: Zapisano 3 bajty dzięki @NieDzejkob. Zaoszczędzono 2 bajty dzięki @xnor za sugerowanie and(raczej niż xnor) operatora. Wykorzystuje następujące mapowanie:

 id | r1 | r2 | r3 | s0 | s1 | s2 | s3 
----+----+----+----+----+----+----+----
 0  | 2  | 4  | 6  | 1  | 3  | 5  | 7  
Neil
źródło
2
Możesz zamienić na (-1)z 7powodu modułowej arytmetyki dla -3 bajtów.
NieDzejkob
@NieDzejkob Thanks! Szkoda, że ​​alephalpha grał w golfa z 28 do 22 bajtów ...
Neil
Fajne rozwiązanie! Możesz wyciąć pareny, zmieniając priorytet operatora:y+x*7**y&7
xnor
@xnor Dzięki, znów jestem przed alephalpha!
Neil
3

TI-BASIC, 165 bajtów

Ans→L₁:{.12345678,.23417865,.34126587,.41238756,.58671342,.67583124,.75862413,.86754231→L₂:For(I,1,8:10fPart(.1int(L₂(I)₁₀^(seq(X,X,1,8:List▶matr(Ans,[B]:If I=1:[B]→[A]:If I-1:augment([A],[B]→[A]:End:[A](L₁(1),L₁(2

Dane wejściowe to lista długości dwóch cali Ans.
Dane wyjściowe to liczba pod (row, column)indeksem w tabeli.

Mogłaby istnieć lepsza metoda kompresji, która oszczędziłaby bajty, ale będę musiał to sprawdzić.

Przykłady:

{1,2
           {1 2}
prgmCDGF1B
               2
{7,4
           {7 4}
prgmCDGF1B
               5

Objaśnienie:
(Dla ułatwienia dodano nowe linie).

Ans→L₁                              ;store the input list into L₁
{.123456 ... →L₂                    ;store the compressed matrix into L₂
                                    ; (line shortened for brevity)
For(I,1,8                           ;loop 8 times
10fPart(.1int(L₂(I)₁₀^(seq(X,X,1,8  ;decompress the "I"-th column of the matrix
List▶matr(Ans,[B]                   ;convert the resulting list into a matrix column and
                                    ; then store it into the "[B]" matrix variable
If I=1                              ;if the loop has just started...
[B]→[A]                             ;then store this column into "[A]", another matrix
                                    ; variable
If I-1                              ;otherwise...
augment([A],[B]→[A]                 ;append this column onto "[A]"
End
[A](L₁(1),L₁(2                      ;get the index and keep it in "Ans"
                                    ;implicit print of "Ans"

Oto 155 bajtów rozwiązanie, ale po prostu koduje matrycę i pobiera indeks.
Uważam, że jest to bardziej nudne, więc nie uczyniłem tego moim oficjalnym oświadczeniem:

Ans→L₁:[[1,2,3,4,5,6,7,8][2,3,4,1,8,7,5,6][3,4,1,2,6,5,8,7][4,1,2,3,7,8,6,5][5,7,6,8,1,3,2,4][6,8,5,7,3,1,4,2][7,6,8,5,4,2,1,3][8,5,7,6,2,4,3,1:Ans(L₁(1),L₁(2

Uwaga: TI-BASIC jest językiem tokenizowanym. Liczba znaków nie jest równa liczbie bajtów.

Tau
źródło
Nie udało się golić jak jeden bajt za pomocą 0-7do1-8
ASCII tylko
Mógłbym, ale musiałbym użyć jeszcze dwóch, aby dodać po jednym do każdego z elementów macierzy. Jednak dobra myśl!
Tau
źle, możesz użyć dowolnego zestawu znaków lol, więc nie musisz używać dwóch kolejnych
tylko ASCII
to może być prawda, ale macierze TI-BASIC są indeksowane 1. to przesłanie polega na tym, aby uzyskać pożądaną wartość (jeśli to sugerujesz. popraw mnie, jeśli się mylę)
Tau
ach, zapomniałem o tym
tylko ASCII
3

Galaretka , 6 bajtów

N⁹¡+%8

Diadadic Link akceptujący pierwszą transformację po prawej stronie i drugą transformację po lewej stronie, która daje transformację złożoną.

Gdzie są transformacje:

as in question:  1    2    3    4    5    6    7    8
transformation: id  90a  180  90c  hor  ver  +ve  -ve
  code's label:  0    2    4    6    1    5    7    3

Wypróbuj online! ... Lub zobacz tabelę odwzorowaną z powrotem na etykiety w pytaniu .

(Argumenty można przyjmować w innej kolejności przy użyciu 6 bajtów, _+Ḃ?%8 ).

W jaki sposób?

Każda etykieta ma długość sekwencji na przemian hori +vetransformacji, która jest równoważna transformacji (np. 180Jest równoważna zhor, +ve, hor, +ve ).

Kompozycja A,B jest równoważna konkatenacji dwóch równoważnych sekwencji i umożliwia uproszczenie odejmowania lub dodawania modulo osiem ...

Na 7, 4przykładzie tego pytania mamy+ve, 90c :
hor, +ve, hor, +ve, hor, +ve, hor , hor, +ve, hor, +ve, hor, +ve

... ale skoro hor, horto idmamy:
hor, +ve, hor, +ve, hor, +ve , +ve, hor, +ve, hor, +ve

... a ponieważ +ve, +veto idmamy:
hor, +ve, hor, +ve, hor , hor, +ve, hor, +ve

... i możemy powtórzyć te anulowania w celu: ..
hor
równoważnego do odjęcia długości (7-6=1 ).

Gdy anulowanie nie jest możliwe, dodajemy tylko długości (np 90a, 180 2+4=6 90c).

Na koniec zauważmy, że sekwencja długości ósemkowej idpozwala nam wziąć wynikową długość modulo osiem.

N⁹¡+%8 - Link: B, A
  ¡    - repeat (applied to chain's left argument, B)...
 ⁹     - ...times: chain's right argument, A
N      - ...action: negate  ...i.e. B if A is even, otherwise -B
   +   - add (A)
    %8 - modulo eight

Jest także o 1 bajt krótszy niż ta implementacja za pomocą indeksów permutacyjnych leksykograficznych:

œ?@ƒ4Œ¿

... monadyczny link akceptujący [first, second], z etykietami:

as in question:  1    2    3    4    5    6    7    8
transformation: id  90a  180  90c  hor  ver  +ve  -ve
  code's label:  1   10   17   19   24    8   15    6
Jonathan Allan
źródło
3

JavaScript (Node.js) , 22 17 bajtów

(x,y)=>y+x*7**y&7

Wypróbuj online! Port mojej odpowiedzi dla Cayley Table of the Dihedral Groupre3)ale grałem w golfa, korzystając z sugestii zawartych w mojej odpowiedzi w języku Python. Wykorzystuje następujące mapowanie:

 id | r1 | r2 | r3 | s0 | s1 | s2 | s3 
----+----+----+----+----+----+----+----
 0  | 2  | 4  | 6  | 1  | 3  | 5  | 7  

Starsze wersje JavaScript mogą być obsługiwane na wiele sposobów dla 22 bajtów:

(x,y)=>(y&1?y-x:y+x)&7
(x,y)=>y-x*(y&1||-1)&7
(x,y)=>y+x*(y<<31|1)&7
Neil
źródło
Mała poprawka - zapisz bajt, curry wejściowy, x=>y=>(y&1?y-x:y+x)&7a następnie wywołaj funkcję za pomocą f(x)(y).
dana
2

Wiąz , 42 bajty 19 bajtów

\a b->and 7<|b+a*7^b

Wersja Neode 's Node.js

Wypróbuj online

Poprzednia wersja:

\a b->and 7<|if and 1 a>0 then a-b else a+b
Evgeniy Malyutin
źródło
1
Ładna pierwsza odpowiedź! Nie wiem, jak programować w Elm, ale czy można usunąć spacje?
MilkyWay90
@ MilkyWay90 nie, to jedna z głównych różnic między językami opartymi na ML, która f xjest wywołaniem funkcji, podobnie jak to, co f(x)oznacza w językach podobnych do C. I nic na to nie poradzę. Ale może być naprawdę przyjemny i mniej zagracony w wielu scenariuszach innych niż golf. Wiąz nie ma operatorów bitowych (takich jak &), więc tutaj and x yjest tylko zwykłe wywołanie funkcji.
Evgeniy Malyutin
Rozumiem, dziękuję za wyjaśnienie!
MilkyWay90
@ W rzeczywistości MilkyWay90 udało mi się odciąć jedną spację (i bajt) za pomocą operatora potoku <|zamiast nawiasu. Dzięki za przesłuchanie!
Evgeniy Malyutin,
Nie ma za co! Jeśli jesteś zainteresowany stworzeniem nowego rozwiązania, możesz poprosić o pomoc w The Nineteenth Byte (nasz czat SE). Jeśli tworzysz wyzwanie kodowania, możesz opublikować je w The Sandbox (na meta) i opublikować link do pytania w The Nineteenth Byte każdego dnia.
MilkyWay90
1

Python, 82 71 bajtów

0-7

-11 bajty dzięki ASCII tylko

lambda a,b:int("27pwpxvfcobhkyqu1wrun3nu1fih0x8svriq0",36)>>3*(a*8+b)&7

TIO

Benjamin Urquhart
źródło
80, python 2 , 76, python 2
tylko ASCII
także 76 i -2, ponieważ f=można je usunąć, ponieważ nie jest rekurencyjne
tylko ASCII
czekaj zgrać, to nie działa
tylko ASCII
2
proszę bardzo, 71
tylko ASCII
wygląda na to, że lepiej sobie radzisz z int.from_byteskodowaniem innym niż UTF, ale ... nie jestem pewien, jak to zrobić na TIO
tylko ASCII
0

Scala , 161 bajtów

Wybór KOMPUTERA jako etykiet.

val m="0123456712307645230154763012675446570213574620316574310274651320"
val s="COMPUTER"
val l=s.zipWithIndex.toMap
def f(a: Char, b: Char)=s(m(l(a)*8+l(b))-48)

Wypróbuj online!

Piotr
źródło
1
to jest kod golfowy: | powinieneś zrobić to tak krótko, jak to możliwe
tylko ASCII
88
Tylko ASCII
Tak, rzuciłem sobie wyzwanie, aby wybrać scala i prawdziwe wytwórnie, a nie tylko natywne 0-7. Spróbuj go pokonać.
Peter
133
Tylko ASCII
118: P
tylko ASCII
0

Scala , 70 bajtów

Wybór 0-7 natywnych liczb całkowitych jako etykiet.

Skompresowano macierz na 32-bajtowy ciąg ASCII, każda para liczb n0, n1 na 1 znak c = n0 + 8 * n1 + 49. Począwszy od 49 do tego, że nie mamy \ w zakodowanym ciągu.

(a:Int,b:Int)=>"9K]oB4h]K9Vh4BoVenAJne3<_X<AX_J3"(a*4+b/2)-49>>b%2*3&7

Wypróbuj online!

Piotr
źródło
-3

Wolfram Language (Mathematica), 7 bajtów (kodowanie UTF-8)

#⊙#2&

Czysta funkcja przyjmująca dwa argumenty. Symbol renderowany tutaj, tak jak w rzeczywistości jest prywatnym symbolem Mathematica F3DE (3 bajty), który reprezentuje funkcję PermutationProduct.

Mathematica wie o grupach dwuściennych i reprezentuje elementy różnych grup jako permutacje, napisane za pomocą Cyclespolecenia. Na przykład uruchomienie polecenia

GroupElements[DihedralGroup[4]]

daje wynik:

{Cycles[{}], Cycles[{{2, 4}}], Cycles[{{1, 2}, {3, 4}}], 
 Cycles[{{1, 2, 3, 4}}], Cycles[{{1, 3}}], Cycles[{{1, 3}, {2, 4}}], 
 Cycles[{{1, 4, 3, 2}}], Cycles[{{1, 4}, {2, 3}}]}

PermutationProduct to funkcja, która zwielokrotnia elementy grupy, gdy są zapisane w tym formularzu.

Ponieważ możemy wybierać własne etykiety, ta funkcja zakłada te etykiety dla elementów grupy; przydział między tymi etykietami a etykietami w stanowisku problemowym jest określony przez:

Cycles[{}] -> 1
Cycles[{{1, 2, 3, 4}}] -> 2
Cycles[{{1, 3}, {2, 4}}] -> 3
Cycles[{{1, 4, 3, 2}}] -> 4
Cycles[{{2, 4}}] -> 5
Cycles[{{1, 3}}] -> 6
Cycles[{{1, 2}, {3, 4}}] -> 7
Cycles[{{1, 4}, {2, 3}}] -> 8

tl; dr Jest wbudowany.

Greg Martin
źródło
8
Etykiety muszą mieć cyfry od 0 do 255 lub pojedyncze bajty.
xnor
W porządku (cieszę się, że odkryłem tę funkcję niezależnie). Czy możesz to wyjaśnić w PO? W tej chwili brzmi to: „wybierz własne etykiety” (podkreślone), a następnie kilka możliwych opcji („możesz ...”).
Greg Martin
1
Och, widzę, jak to czytasz; przepraszam, że jestem niejasny i poprowadziłem cię złą drogą. Pozwól, że spróbuję to przeredagować.
xnor