Composição do grupo Dédrico D4 com etiquetas personalizadas

14

O grupo diédrico D4 é o grupo de simetria do quadrado, ou seja, os movimentos que transformam um quadrado em si mesmo por meio de rotações e reflexões. Consiste em 8 elementos: rotações de 0, 90, 180 e 270 graus e reflexões nos eixos horizontal, vertical e dois diagonais.

Os 8 elementos de D4 atuando na praça.

As imagens são desta página adorável de Larry Riddle.

Esse desafio é sobre a composição desses movimentos: dados dois movimentos, produza o movimento equivalente a executá-los um após o outro. Por exemplo, fazer o movimento 7 seguido pelo movimento 4 é o mesmo que fazer o movimento 5.

Exemplo de composição

Observe que alternar a ordem para mover 4 e depois mover 7 produz o movimento 6.

Os resultados estão tabulados abaixo; esta é a tabela de Cayley do grupo D4 . Por exemplo, as entradas 7,4 devem produzir a saída 5 .

12345678123456781234567823418756341265874123786557681324685731427685421385762431

Desafio

Seu objetivo é implementar essa operação no menor número de bytes possível, mas, além do código, você também escolhe os rótulos que representam os movimentos de 1 a 8. Os rótulos devem ter 8 números distintos, de 0 a 255 , ou o número 8. caracteres de bytes que seus pontos de código representam.

Seu código receberá dois dos rótulos dos 8 que você escolheu e deve exibir o rótulo que corresponde à sua composição no grupo diédrico D4 .

Exemplo

Digamos que você tenha escolhido os caracteres C, O, M, P, U, T, E, R para os movimentos de 1 a 8, respectivamente. Em seguida, seu código deve implementar esta tabela.

COMPUTERCOMPUTERCOMPUTEROMPCREUTMPCOTUREPCOMERTUUETRCMOPTRUEMCPOETRUPOCMRUETOPMC

Dadas as entradas E e P, você deve enviar U. Suas entradas sempre serão duas das letras C, O, M, P, U, T, E, R, e sua saída sempre deve ser uma dessas letras.

Tabela de texto para copiar

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
fonte
Your choice of labels doesn't count against your code length.mente elaborando? Tal como está, posso codificar a matriz no meu código e afirmar que não conta na minha pontuação.
Benjamin Urquhart
2
@BenjaminUrquhart Eu estava tentando dizer que o tamanho do seu código é exatamente o mesmo e dizer que escolher rótulos com vários dígitos não custa nada extra. Parece que essa linha é mais confusa que útil, então eu a removerei.
xnor

Respostas:

10

Ruby , 18 bytes

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

Experimente online!

Usa os seguintes números de código de 0 a 7

Em ordem nativa para o código:

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

Em ordem de acordo com a pergunta

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

Explicação

/representa um giro na linha y=xe |representa um giro no eixo y.

É possível gerar qualquer uma das simetrias do grupo D4 alternando alternadamente nessas duas linhas. Por exemplo, /seguidas de |give, /|que é uma rotação de 90 graus no sentido anti-horário.

O número total de lançamentos consecutivos fornece uma representação muito conveniente para manipulação aritmética.

Se o primeiro movimento for uma rotação, podemos simplesmente adicionar o número de movimentos:

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

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

Se o primeiro movimento é um reflexo, descobrimos que temos alguns reflexos /e |símbolos idênticos um ao lado do outro. Como a reflexão é auto-inversa, podemos cancelar esses movimentos um a um. Então, precisamos subtrair um movimento do outro

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
fonte
1
Você pode substituir o por ~0com 7aritmética modular.
NieDzejkob
Ótimo método e explicação! A maneira como os flips são cancelados deixa muito claro por que os rótulos são adicionados ou subtraídos.
xnor
7

Wolfram Language (Mathematica) , 31 bytes

Usando números inteiros 0,5,2,7,1,3,6,4 como rótulos.

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

Experimente online!

Explicação:

O grupo diédrico D4 é isomórfico ao grupo da matriz unitriangular de grau três sobre o campo F2 :

D4U(3,2):={(1ab01c001)a,b,cF2}.

E nós temos

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

que pode ser facilmente escrito em operações bit a bit.

alefalpha
fonte
Uma bonita derivação - eu não sabia sobre esse isomorfismo.
xnor
5

Wolfram Language (Mathematica) , 51 bytes

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

Experimente online!

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

Estes estão {3210, 0321, 1032, 2103, 0123, 2301, 3012, 1230}na base 4. Felizmente, 256 = 4 ^ 4.


Implementação de nível inferior, também 51 bytes

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

Experimente online!

attinat
fonte
4

Python 2 , 22 bytes

0,6,1,7,2,3,5,4

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

Experimente online!

alefalpha
fonte
4

Python 2 , 26 23 21 bytes

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  
Neil
fonte
2
Você pode substituir (-1)por 7causa da aritmética modular para -3 bytes.
NieDzejkob
@NieDzejkob Thanks! Vergonha que alephalpha golfed sua resposta para baixo de 28 para 22 bytes embora ...
Neil
Ótima solução! Você pode cortar os parênteses alterando a precedência do operador:y+x*7**y&7
xnor
@xnor Obrigado, estou à frente de alephalpha novamente!
Neil
3

TI-BASIC, 165 bytes

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

Entrada é uma lista de comprimento dois Ans.
Saída é o número no(row, column) índice da tabela.

Poderia haver um método de compactação melhor que economizasse bytes, mas precisarei analisar isso.

Exemplos:

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

Explicação:
(Novas linhas foram adicionadas para facilitar a leitura.)

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"

Aqui está uma solução de 155 bytes , mas apenas codifica a matriz e obtém o índice.
Eu achei que era mais chato, então não fiz a minha inscrição oficial:

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 é um idioma tokenizado. Contagem de caracteres não é igual à contagem de bytes.

Tau
fonte
Você não conseguia se barbear como um byte usando 0-7to1-8
ASCII-only
Eu poderia, mas teria que usar mais dois para adicionar um a cada um dos elementos da matriz. Bom pensamento, no entanto!
Tau
errado, você pode usar qualquer conjunto de caracteres, lol, para não precisar usar mais dois
somente ASCII
isso pode ser verdade, mas as matrizes do TI-BASIC são indexadas 1. esta submissão depende de que para obter o valor queria (se é isso que você está insinuando me corrija se eu estiver errado.)
Tau
ah, esqueci disso
apenas ASCII
3

Gelatina , 6 bytes

N⁹¡+%8

Um link diádico que aceita a primeira transformação à direita e a segunda transformação à esquerda, que produz a transformação composta.

Onde as transformações são:

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

Experimente online! ... Ou veja a tabela mapeada de volta para os rótulos na pergunta .

(Os argumentos podem ser tomados na outra ordem usando o 6 byter, _+Ḃ?%8 )

Quão?

Cada etiqueta é o comprimento de uma sequência de alternância hore +vetransformação que é equivalente à transformação (por exemplo, 180é equivalente ahor, +ve, hor, +ve ).

A composição A,B é equivalente à concatenação das duas seqüências equivalentes e permite simplificar a subtração ou adição do módulo oito ...

Usando o 7, 4exemplo da pergunta, temos o seguinte +ve, 90c:
hor, +ve, hor, +ve, hor, +ve, hor , hor, +ve, hor, +ve, hor, +ve

... mas como hor, horé idque temos:
hor, +ve, hor, +ve, hor, +ve , +ve, hor, +ve, hor, +ve

... e uma vez que +ve, +veé id, temos:
hor, +ve, hor, +ve, hor , hor, +ve, hor, +ve

... e podemos repetir esses cancelamentos para:
hor
..equivalente à subtração dos comprimentos ( 7-6=1).

90a, 180 2+4=6 90c

Por fim, observe que uma sequência de comprimento oito é idpara que possamos pegar o módulo de comprimento de sequência resultante oito.

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

Também é 1 byte menor que esta implementação usando índices de permutação lexicográficos:

œ?@ƒ4Œ¿

... um link monádico aceitando [first, second], com rótulos:

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
fonte
3

JavaScript (Node.js) , 22 17 bytes

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

D3

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

Versões mais antigas do JavaScript podem ser suportadas de várias maneiras por 22 bytes:

(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
fonte
Pequena melhoria - salve um byte fazendo um curry de entrada x=>y=>(y&1?y-x:y+x)&7e chame sua função usando f(x)(y).
dana
2

Olmo , 42 bytes 19 bytes

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

Porta da versão Node.js do Neil

Experimente online

Versão anterior:

\a b->and 7<|if and 1 a>0 then a-b else a+b
Evgeniy Malyutin
fonte
1
Boa primeira resposta! Não sei programar no Elm, mas é possível remover espaços?
MilkyWay90
@ MilkyWay90 não, é uma das principais diferenças de linguagens baseadas em ML que f xé uma chamada de função, assim como o que f(x)significa em linguagens C. E você não pode evitar. Mas pode ser realmente agradável e menos confuso em muitos cenários que não são de golfe. Elm não possui operadores bit a bit (como &), portanto, and x yé apenas uma chamada de função simples aqui.
Evgeniy Malyutin
Entendo, obrigado por explicar!
MilkyWay90
@ MilkyWay90, na verdade, eu consegui cortar um espaço (e um byte) usando o operador de pipe em <|vez de parênteses. Obrigado por questionar isso!
Evgeniy Malyutin
Seja bem-vindo! Se você estiver interessado em criar uma nova solução, poderá pedir ajuda no The XIX XIX Byte (nossa sala de bate-papo do SE). Se você estiver criando um desafio de codificação, poderá postá-lo na The Sandbox (na meta) e postar o link da pergunta no The XIX XIX Byte todos os dias.
MilkyWay90
1

Python, 82 71 bytes

0-7

-11 bytes graças apenas ao ASCII

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

TIO

Benjamin Urquhart
fonte
80, python 2 , 76, python 2
somente ASCII
também 76 e -2 porque f=pode ser removido porque não é recursivo
somente ASCII
aguarde rip, ele não funciona
ASCII-only
2
aqui vamos nós, 71
somente ASCII
Parece que você poderia fazer melhor com int.from_bytese codificação não-UTF, mas ... não sei como fazer isso no TIO
ASCII-only
0

Scala , 161 bytes

Escolhendo COMPUTADOR como etiquetas.

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)

Experimente online!

Pedro
fonte
1
este é o código golf: | você deve torná-lo o mais curto possível
apenas ASCII
88
Somente ASCII
Sim, eu me desafiei a usar scala e etiquetas reais, não apenas nativas de 0 a 7. Tente vencê-lo.
Peter
133
somente ASCII
118: P
somente ASCII
0

Scala , 70 bytes

Escolhendo 0-7 números inteiros nativos como rótulos.

Compactou a matriz em uma string ASCII de 32 bytes, cada par de números n0, n1 em um caractere c = n0 + 8 * n1 + 49. A partir de 49, não temos \ na string codificada.

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

Experimente online!

Pedro
fonte
-3

Wolfram Language (Mathematica), 7 bytes (codificação UTF-8)

#⊙#2&

Uma função pura usando dois argumentos. O símbolo aqui representado como na verdade é o símbolo Unicode privado F3DE do Mathematica (3 bytes), que representa a funçãoPermutationProduct .

O Mathematica conhece grupos dédricos e representa os elementos de vários grupos como permutações, escritas usando o Cyclescomando Por exemplo, executando o comando

GroupElements[DihedralGroup[4]]

produz a saída:

{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 é a função que multiplica elementos de grupo quando escritos neste formulário.

Como podemos escolher nossos próprios rótulos, essa função assume esses rótulos para os elementos do grupo; a associação entre esses rótulos e os da postagem do problema é dada por:

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 Há um builtin.

Greg Martin
fonte
8
Os rótulos devem ser números de 0 a 255 ou bytes únicos.
xnor
É justo (estou feliz por ter descoberto essa função independentemente). Você pode esclarecer isso no OP? No momento, ele lê como "escolha seus próprios rótulos" (enfatizado) e, em seguida, algumas opções possíveis ("você pode ...").
Greg Martin
1
Oh, eu vejo como você está lendo; desculpe por não estar claro aqui e por levá-lo ao caminho errado. Deixe-me tentar reformulá-lo.
xnor