Composizione del gruppo diedro D4 con etichette personalizzate


14

Il gruppo diedrico D4 è il gruppo di simmetria del quadrato, ovvero le mosse che trasformano un quadrato in se stesso tramite rotazioni e riflessioni. È composto da 8 elementi: rotazioni di 0, 90, 180 e 270 gradi e riflessi sugli assi orizzontale, verticale e due diagonali.

Gli 8 elementi di D4 che agiscono sul quadrato.

Le immagini provengono tutte da questa adorabile pagina di Larry Riddle.

Questa sfida riguarda la composizione di queste mosse: date due mosse, produce la mossa che equivale a farle una dopo l'altra. Ad esempio, fare la mossa 7 seguita dalla mossa 4 equivale a fare la mossa 5.

Esempio di composizione

Nota che cambiando l'ordine di spostare 4, quindi spostare 7, si ottiene invece la mossa 6.

I risultati sono riportati di seguito; questa è la tabella Cayley del gruppo D4 . Quindi, ad esempio, input 7,4 dovrebbero produrre l'uscita 5 .

12345678123456781234567823418756341265874123786557681324685731427685421385762431

Sfida

Il tuo obiettivo è implementare questa operazione nel minor numero di byte possibile, ma oltre al codice, scegli anche le etichette che rappresentano le mosse da 1 a 8. Le etichette devono essere 8 numeri distinti da 0 a 255 o 8 -byte caratteri che rappresentano i loro punti di codice.

Al tuo codice verranno assegnate due delle etichette tra le 8 che hai scelto e deve generare l'etichetta corrispondente alla loro composizione nel gruppo diedrico D4 .

Esempio

Supponi di aver scelto i caratteri C, O, M, P, U, T, E, R per le mosse da 1 a 8 rispettivamente. Quindi, il codice dovrebbe implementare questa tabella.

COMPUTERCOMPUTERCOMPUTEROMPCREUTMPCOTUREPCOMERTUUETRCMOPTRUEMCPOETRUPOCMRUETOPMC

Dati gli input E e P, dovresti produrre U. I tuoi input saranno sempre due delle lettere C, O, M, P, U, T, E, R e il tuo output dovrebbe essere sempre una di queste lettere.

Tabella di testo per la copia

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

Your choice of labels doesn't count against your code length.elaborando la mente? Allo stato attuale, posso codificare la matrice nel mio codice e affermare che non conta per il mio punteggio.
— Benjamin Urquhart,

2
@BenjaminUrquhart Stavo cercando di dire che la lunghezza del tuo codice è solo la lunghezza del tuo codice e, per esempio, scegliere le etichette multidigit non costa nulla in più. Sembra che quella riga sia più confusa che utile, quindi la rimuoverò.
— xnor

Risposte:


10

Rubino , 18 byte

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

Ungolfed

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

Provalo online!

Utilizza i seguenti numeri di codifica da 0 a 7

Per essere nativo del codice:

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

In ordine secondo la domanda

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

Spiegazione

/rappresenta un ribaltamento nella linea y=xe |rappresenta un ribaltamento nell'asse y.

È possibile generare una qualsiasi delle simmetrie del gruppo D4 capovolgendo alternativamente queste due linee. Ad esempio, /seguito da |dà /|che è una rotazione di 90 gradi in senso antiorario.

Il numero totale di lanci consecutivi offre una rappresentazione molto conveniente per la manipolazione aritmetica.

Se la prima mossa è una rotazione, possiamo semplicemente aggiungere il numero di lanci:

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

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

Se la prima mossa è un riflesso, scopriamo che abbiamo alcuni riflessi /e |simboli identici uno accanto all'altro. Dato che il riflesso è auto-inverso, possiamo cancellare questi lanci uno per uno. Quindi dobbiamo sottrarre una mossa dall'altra

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 ) / 

1
È possibile sostituire il ~0con a 7causa dell'aritmetica modulare.
— NieDzejkob,

Ottimo metodo e spiegazione! Il modo in cui i flip si annullano rende molto chiaro il motivo per cui le etichette vengono aggiunte o sottratte.
— xnor

7

Wolfram Language (Mathematica) , 31 byte

Utilizzando numeri interi 0,5,2,7,1,3,6,4 come etichette.

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

Provalo online!

Spiegazione:

Il gruppo diedrico D4 è isomorfo rispetto al gruppo unitario a matrice triangolare di grado tre sul campo F2 :

D4≅U(3,2):={(1ab01c001)∣a,b,c∈F2}.

E noi abbiamo

(1a1b101c1001)⋅(1a2b201c2001)=(1a1+a2b1+b2+a1c201c1+c2001),

che può essere facilmente scritto in operazioni bit a bit.


Una bella derivazione - non sapevo di questo isomorfismo.
— xnor

5

Wolfram Language (Mathematica) , 51 byte

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

Provalo online!

Usando le etichette {228, 57, 78, 147, 27, 177, 198, 108}.

Questi sono {3210, 0321, 1032, 2103, 0123, 2301, 3012, 1230}nella base 4. Fortunatamente, 256 = 4 ^ 4.


Implementazione di livello inferiore, anche 51 byte

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

Provalo online!



4

Python 2 , 26 23 21 byte

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

D3andxnor

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

2
È possibile sostituire (-1)con a 7causa dell'aritmetica modulare per -3 byte.
— NieDzejkob,

@NieDzejkob Grazie! Peccato che alephalpha abbia golfato la sua risposta da 28 a 22 byte però ...
— Neil

Bella soluzione! Puoi tagliare le parentesi modificando la precedenza dell'operatore:y+x*7**y&7
— xnor

@xnor Grazie, sono di nuovo davanti a alephalpha!
— Neil

3

TI-BASIC, 165 byte

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

L'input è un elenco di lunghezza due pollici Ans.
L'output è il numero (row, column)nell'indice nella tabella.

Potrebbe esserci un metodo di compressione migliore che salverebbe i byte, ma dovrò esaminarlo.

Esempi:

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

Spiegazione:
(Newline sono stati aggiunti per la leggibilità.)

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"

Ecco una soluzione da 155 byte , ma codifica semplicemente la matrice e ottiene l'indice.
Ho trovato che fosse più noioso, quindi non l'ho fatto la mia presentazione ufficiale:

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

Nota: TI-BASIC è un linguaggio tokenizzato. Il conteggio dei caratteri non equivale al conteggio dei byte.


Non puoi raderti come un byte usando 0-7to1-8
— ASCII-only

Potrei, ma poi dovrei usarne altri due per aggiungerne uno a ciascuno degli elementi della matrice. Buona idea, comunque!
— Tau,

sbagliato, puoi usare qualsiasi set di caratteri lol, quindi non devi usarne altri due
— solo ASCII

questo può essere vero, ma le matrici di TI-BASIC sono 1 indicizzate. questa presentazione si basa su quello per ottenere il valore desiderato (se è quello che stai insinuando. correggimi se sbaglio)
— Tau

ah, me ne sono dimenticato
— ASCII-only

3

Gelatina , 6 byte

N⁹¡+%8

Un collegamento diadico che accetta la prima trasformata a destra e la seconda trasformata a sinistra che produce la trasformata composita.

Dove sono le trasformazioni:

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

Provalo online! ... O vedi la tabella mappata di nuovo sulle etichette nella domanda .

(Gli argomenti potrebbero essere presi nell'altro ordine usando il 6 byter, _+Ḃ?%8)

Come?

Ogni etichetta è la lunghezza di una sequenza di alternanza hore +vetrasformazioni che è equivalente alla trasformazione (ad esempio 180è equivalente a hor, +ve, hor, +ve).

La composizione A,Bè equivalente alla concatenazione delle due sequenze equivalenti e consente la semplificazione della sottrazione o aggiunta modulo otto ...

Usando l' 7, 4esempio della domanda abbiamo +ve, 90cche è:
hor, +ve, hor, +ve, hor, +ve, hor , hor, +ve, hor, +ve, hor, +ve

... ma dal momento che hor, horè idche abbiamo:
hor, +ve, hor, +ve, hor, +ve , +ve, hor, +ve, hor, +ve

... e dal momento che +ve, +veè idabbiamo:
hor, +ve, hor, +ve, hor , hor, +ve, hor, +ve

... e possiamo ripetere queste cancellazioni per:
hor
..equivalente alla sottrazione delle lunghezze ( 7-6=1).

90a, 180 → 2+4=6 → 90c

Infine, si noti che una sequenza di lunghezza otto è idquindi possiamo prendere la lunghezza di sequenza risultante modulo otto.

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

È inoltre più corto di 1 byte rispetto a questa implementazione usando gli indici di permutazione lessicografica:

œ?@ƒ4Œ¿

... un collegamento monadico che accetta [first, second], con etichette:

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

3

JavaScript (Node.js) , 22 17 byte

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

D3ma ho giocato a golf usando i suggerimenti sulla mia risposta Python. Utilizza il seguente mapping:

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

Le versioni precedenti di JavaScript possono essere supportate in diversi modi per 22 byte:

(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

Piccolo miglioramento: salva un byte eseguendo il curry dell'input, x=>y=>(y&1?y-x:y+x)&7quindi chiama la tua funzione utilizzando f(x)(y).
— dana,


2

Olmo , 42 byte 19 byte

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

Port of the Neil's Versione Node.js

Provalo online

Versione precedente:

\a b->and 7<|if and 1 a>0 then a-b else a+b

1
Bella prima risposta! Non so programmare in Elm, ma è possibile rimuovere gli spazi?
— MilkyWay90,

@ MilkyWay90 no, è una delle principali differenze dei linguaggi basati su ML che f xè una chiamata di funzione, proprio come ciò che f(x)significa nei linguaggi di tipo C. E non puoi farci niente. Ma può essere davvero bello e meno ingombrante in molti scenari non golfistici. Elm non ha operatori bit a bit (come &) quindi and x yè solo una semplice chiamata di funzione qui.
— Evgeniy Malyutin

Vedo, grazie per aver spiegato!
— MilkyWay90,

@ MilkyWay90 in realtà, sono riuscito a tagliare uno spazio (e un byte) usando l'operatore pipe <|invece della parentesi. Grazie per averlo messo in discussione!
— Evgeniy Malyutin

Prego! Se sei interessato a creare una nuova soluzione, puoi chiedere aiuto su The Nineteenth Byte (la nostra chat di SE). Se stai creando una sfida di codifica, puoi pubblicarla su The Sandbox (su meta) e pubblicare il link alla domanda su The Nineteenth Byte ogni giorno.
— MilkyWay90,


0

Scala , 161 byte

Scelta di COMPUTER come etichette.

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)

Provalo online!


1
questo è il codice golf: | dovresti renderlo il più breve possibile
— solo ASCII


Sì, mi sono sfidato ad andare con scala e etichette reali, non solo nativi 0-7. Prova a batterlo.
— Peter,



0

Scala , 70 byte

Scegliere 0-7 numeri interi nativi come etichette.

Compresso la matrice in stringa ASCII a 32 byte, ogni coppia di numeri n0, n1 in 1 carattere c = n0 + 8 * n1 + 49. A partire da 49 a quello non abbiamo \ nella stringa codificata.

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

Provalo online!




-3

Wolfram Language (Mathematica), 7 byte (codifica UTF-8)

#⊙#2&

Una funzione pura che prende due argomenti. Il simbolo reso qui come⊙ realtà è il simbolo Unicode privato di Mathematica F3DE (3 byte), che rappresenta la funzionePermutationProduct .

Mathematica conosce gruppi diedrici e rappresenta gli elementi di vari gruppi come permutazioni, scritti usando il Cyclescomando. Ad esempio, eseguendo il comando

GroupElements[DihedralGroup[4]]

produce l'output:

{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 è la funzione che moltiplica gli elementi del gruppo quando è scritta in questo modulo.

Poiché ci è consentito scegliere le nostre etichette, questa funzione assume queste etichette per gli elementi del gruppo; l'associazione tra queste etichette e quelle nel post del problema è data da:

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 C'è un builtin.


8
Le etichette devono essere numeri da 0 a 255 o byte singoli.
— xnor

Abbastanza giusto (sono felice di aver scoperto questa funzione a prescindere). Puoi chiarirlo nell'OP? In questo momento si legge come "scegli le tue etichette" (sottolineato), quindi un paio di possibili scelte ("potresti ...").
— Greg Martin,

1
Oh, vedo come lo stai leggendo; mi dispiace di non essere chiaro qui e di averti condotto sulla strada sbagliata. Vorrei provare a riformularlo.
— xnor
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.