Composition du groupe dièdre D4 avec étiquettes personnalisées

14

Le groupe dièdre est le groupe de symétrie du carré, c'est-à-dire les mouvements qui transforment un carré à lui-même via des rotations et des réflexions. Il se compose de 8 éléments: des rotations de 0, 90, 180 et 270 degrés et des réflexions sur les axes horizontal, vertical et deux diagonaux.D4

Les 8 éléments de D4 agissant sur le carré.

Les images sont toutes issues de cette jolie page de Larry Riddle.

Ce défi consiste à composer ces mouvements: compte tenu de deux mouvements, sortez le mouvement qui équivaut à les faire l'un après l'autre. Par exemple, faire le coup 7 suivi du coup 4 revient au même que faire le coup 5.

Exemple de composition

Notez que changer l'ordre de déplacer 4 puis déplacer 7 produit le mouvement 6 à la place.

Les résultats sont présentés dans le tableau ci-dessous; c'est la table Cayley du groupe . Ainsi, par exemple, les entrées devraient produire la sortie .D47,45

12345678123456781234567823418756341265874123786557681324685731427685421385762431

Défi

Votre objectif est d'implémenter cette opération dans le moins d'octets possible, mais en plus du code, vous choisissez également les étiquettes qui représentent les déplacements de 1 à 8. Les étiquettes doivent être constituées de 8 nombres distincts de 0 à 255 , ou les 8 -octets représentent leurs points de code.

Votre code recevra deux des étiquettes parmi les 8 que vous avez choisies et doit sortir l'étiquette qui correspond à leur composition dans le groupe dièdre D4 .

Exemple

Supposons que vous ayez choisi les caractères C, O, M, P, U, T, E, R pour les mouvements 1 à 8 respectivement. Ensuite, votre code doit implémenter cette table.

COMPUTERCOMPUTERCOMPUTEROMPCREUTMPCOTUREPCOMERTUUETRCMOPTRUEMCPOETRUPOCMRUETOPMC

Étant donné les entrées E et P, vous devez sortir U. Vos entrées seront toujours deux des lettres C, O, M, P, U, T, E, R, et votre sortie devrait toujours être l'une de ces lettres.

Tableau de texte pour la copie

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
la source
Your choice of labels doesn't count against your code length.l'esprit d'élaborer? En l'état, je peux coder en dur la matrice dans mon code et prétendre qu'elle ne compte pas dans mon score.
Benjamin Urquhart
2
@BenjaminUrquhart J'essayais de dire que la longueur de votre code est juste la longueur de votre code, et dire que choisir des étiquettes à plusieurs chiffres ne coûte rien de plus. Il semble que cette ligne soit plus déroutante qu'utile, je vais donc la supprimer.
xnor

Réponses:

10

Rubis , 18 octets

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

Non golfé

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

Essayez-le en ligne!

Utilise les numéros de codage suivants de 0 à 7

Dans l'ordre natif du code:

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

Pour la question

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

Explication

/représente un retournement dans la ligne y=xet |représente un retournement dans l'axe y.

Il est possible de générer n'importe laquelle des symétries du groupe D4 en inversant alternativement ces deux lignes, par exemple /suivi de |donne /|qui est une rotation de 90 degrés dans le sens inverse des aiguilles d'une montre.

Le nombre total de flips consécutifs donne une représentation très pratique pour la manipulation arithmétique.

Si le premier coup est une rotation, on peut simplement ajouter le nombre de flips:

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

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

Si le premier mouvement est une réflexion, nous constatons que nous avons des réflexions /et des |symboles identiques les uns à côté des autres. La réflexion étant auto-inverse, nous pouvons annuler ces flips un par un. Nous devons donc soustraire un mouvement de l'autre

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
la source
1
Vous pouvez remplacer le ~0par en 7raison de l'arithmétique modulaire.
NieDzejkob
Grande méthode et explication! La façon dont les flips s'annulent montre clairement pourquoi les étiquettes s'ajoutent ou se soustraient.
xnor
7

Wolfram Language (Mathematica) , 31 octets

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

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

Essayez-le en ligne!

Explication:

4F2

4U(3,2): ={(1uneb01c001)une,b,cF2}.

Et nous avons

(1une1b101c1001)(1une2b201c2001)=(1une1+une2b1+b2+une1c201c1+c2001),

qui peut facilement être écrit en opérations au niveau du bit.

alephalpha
la source
Une jolie dérivation - je ne connaissais pas cet isomorphisme.
xnor
5

Wolfram Language (Mathematica) , 51 octets

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

Essayez-le en ligne!

À l'aide d'étiquettes {228, 57, 78, 147, 27, 177, 198, 108}.

Ce sont {3210, 0321, 1032, 2103, 0123, 2301, 3012, 1230}en base 4. Heureusement, 256 = 4 ^ 4.


Implémentation de niveau inférieur, également 51 octets

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

Essayez-le en ligne!

attinat
la source
4

Python 2 , 22 octets

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

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

Essayez-le en ligne!

alephalpha
la source
4

Python 2 , 26 23 21 octets

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

3andxnor

 id | r1 | r2 | r3 | s0 | s1 | s2 | s3 
----+----+----+----+----+----+----+----
 0  | 2  | 4  | 6  | 1  | 3  | 5  | 7  
Neil
la source
2
Vous pouvez le remplacer (-1)par en 7raison de l'arithmétique modulaire pour -3 octets.
NieDzejkob
@NieDzejkob Merci! Dommage que Alephalpha ait fait passer sa réponse de 28 à 22 octets ...
Neil
Bonne solution! Vous pouvez couper les parens en modifiant la priorité de l'opérateur:y+x*7**y&7
xnor
@xnor Merci, j'ai de nouveau une longueur d'avance sur alephalpha!
Neil
3

TI-BASIC, 165 octets

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'entrée est une liste de deux pouces de longueur Ans.
La sortie est le nombre à l' (row, column)index dans le tableau.

Il pourrait y avoir une meilleure méthode de compression qui permettrait d'économiser des octets, mais je vais devoir y réfléchir.

Exemples:

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

Explication:
(Des sauts de ligne ont été ajoutés pour plus de lisibilité.)

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"

Voici une solution à 155 octets , mais elle code simplement la matrice et obtient l'index.
Je l'ai trouvé plus ennuyeux, donc je n'en ai pas fait ma soumission officielle:

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

Remarque: TI-BASIC est un langage à jetons. Le nombre de caractères n'est pas égal au nombre d'octets.

Tau
la source
Ne pourriez-vous pas vous raser comme un octet en utilisant 0-7to1-8
ASCII uniquement
Je pourrais, mais je devrais alors en utiliser deux de plus pour en ajouter un à chacun des éléments de la matrice. Bonne pensée cependant!
Tau
faux, vous pouvez utiliser n'importe quel jeu de caractères lol, vous n'avez donc pas à en utiliser deux de plus
ASCII uniquement
cela peut être vrai, mais les matrices de TI-BASIC sont indexées sur 1. cette soumission s'appuie sur cela pour obtenir la valeur souhaitée (si c'est ce que vous sous-entendez. corrigez-moi si je me trompe)
Tau
ah, j'ai oublié ça
ASCII uniquement
3

Gelée , 6 octets

N⁹¡+%8

Un lien dyadique acceptant la première transformation à droite et la deuxième transformation à gauche qui donne la transformation composite.

Où se trouvent les transformations:

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

Essayez-le en ligne! ... Ou voyez le tableau retranscrit sur les étiquettes de la question .

(Les arguments peuvent être repris dans l'autre ordre en utilisant le 6 octet, _+Ḃ?%8)

Comment?

Chaque étiquette est la longueur d'une séquence d'alternances horet de +vetransformations qui est équivalente à la transformation (par exemple 180est équivalente à hor, +ve, hor, +ve).

La composition A,Best équivalente à la concaténation des deux séquences équivalentes, et permet une simplification en soustraction ou addition modulo huit ...

En utilisant l' 7, 4exemple de la question que nous avons +ve, 90cqui est:
hor, +ve, hor, +ve, hor, +ve, hor , hor, +ve, hor, +ve, hor, +ve

... mais depuis hor, horest que idnous avons:
hor, +ve, hor, +ve, hor, +ve , +ve, hor, +ve, hor, +ve

... et depuis +ve, +veest que idnous avons:
hor, +ve, hor, +ve, hor , hor, +ve, hor, +ve

... et nous pouvons répéter ces annulations pour:
hor
..équivalent à la soustraction des longueurs ( 7-6=1).

Lorsqu'aucune annulation n'est possible, nous ajoutons simplement les longueurs (comme 90a, 180 2+4=6 90c).

Enfin, notez qu'une séquence de longueur huit est idainsi nous pouvons prendre la longueur de séquence résultante modulo huit.

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

Il est également 1 octet plus court que cette implémentation utilisant des index de permutation lexicographiques:

œ?@ƒ4Œ¿

... un lien monadique acceptant [first, second], avec des étiquettes:

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
la source
3

JavaScript (Node.js) , 22 17 octets

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

Essayez-le en ligne! Port de ma réponse à Cayley Table du groupe dièdre3mais j'ai joué au golf en utilisant les suggestions de ma réponse Python. Utilise le mappage suivant:

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

Les anciennes versions de JavaScript peuvent être prises en charge de différentes manières pour 22 octets:

(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
la source
Petite amélioration - enregistrez un octet en curryant x=>y=>(y&1?y-x:y+x)&7puis appelez votre fonction en utilisant f(x)(y).
dana
2

Orme , 42 octets 19 octets

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

Port de la version Neil's Node.js

Essayez-le en ligne

La version précédente:

\a b->and 7<|if and 1 a>0 then a-b else a+b
Evgeniy Malyutin
la source
1
Belle première réponse! Je ne sais pas comment programmer dans Elm, mais est-il possible de supprimer des espaces?
MilkyWay90
@ MilkyWay90 non, c'est l'une des principales différences des langages basés sur ML qui f xest un appel de fonction, tout comme ce que cela f(x)signifie dans les langages de type C. Et vous ne pouvez rien y faire. Mais il peut être vraiment agréable et moins encombré dans de nombreux scénarios non golfiques. Elm n'a pas d'opérateurs au niveau du bit (comme &) donc and x yc'est juste un simple appel de fonction ici.
Evgeniy Malyutin
Je vois, merci d'avoir expliqué!
MilkyWay90
@ MilkyWay90 en fait, j'ai réussi à couper un espace (et un octet) à l'aide d'un opérateur de tuyau <|au lieu de parenthèses. Merci d'avoir remis cela en question!
Evgeniy Malyutin
Vous êtes les bienvenus! Si vous souhaitez créer une nouvelle solution, vous pouvez demander de l'aide sur The Nineteenth Byte (notre salon de discussion SE). Si vous créez un défi de codage, vous pouvez le publier sur The Sandbox (sur la méta) et publier le lien vers la question sur The Nineteenth Byte tous les jours.
MilkyWay90
1

Python, 82 71 octets

0-7

-11 octets grâce à ASCII uniquement

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

TIO

Benjamin Urquhart
la source
80, python 2 , 76, python 2
ASCII uniquement
également 76 , et -2 car f=peut être supprimé car il n'est pas récursif
ASCII uniquement
attendez rip, cela ne fonctionne pas
ASCII uniquement
2
c'est parti, 71
ASCII uniquement
semble que vous pourriez faire mieux avec int.from_bytesun encodage non UTF, mais ... vous ne savez pas comment faire cela sur TIO
ASCII uniquement
0

Scala , 161 octets

Choisir ORDINATEUR comme étiquettes.

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)

Essayez-le en ligne!

Peter
la source
1
c'est le golf de code: | vous êtes censé le rendre aussi court que possible
ASCII uniquement
88
ASCII uniquement
Ouais, je me suis mis au défi de choisir la scala et les vrais labels, pas seulement le natif 0-7. Essayez de le battre.
Peter
133
ASCII uniquement
118: P
ASCII uniquement
0

Scala , 70 octets

Choix de 0 à 7 entiers natifs comme étiquettes.

Compression de la matrice en chaîne ASCII de 32 octets, chaque paire de nombres n0, n1 en 1 caractère c = n0 + 8 * n1 + 49. À partir de 49, nous n'avons pas \ dans la chaîne codée.

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

Essayez-le en ligne!

Peter
la source
-3

Wolfram Language (Mathematica), 7 octets (encodage UTF-8)

#⊙#2&

Une fonction pure prenant deux arguments. Le symbole rendu ici est en fait le symbole Unicode privé F3DE de Mathematica (3 octets), qui représente la fonction PermutationProduct.

Mathematica connaît les groupes dièdres et représente les éléments de divers groupes sous forme de permutations, écrits à l'aide de la Cyclescommande. Par exemple, exécuter la commande

GroupElements[DihedralGroup[4]]

donne la sortie:

{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 est la fonction qui multiplie les éléments de groupe lorsqu'elle est écrite sous cette forme.

Puisque nous sommes autorisés à choisir nos propres étiquettes, cette fonction suppose ces étiquettes pour les éléments du groupe; L'association entre ces étiquettes et celles du poste problématique est donnée par:

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 Il y a un intégré.

Greg Martin
la source
8
Les étiquettes doivent être des nombres de 0 à 255 ou des octets simples.
xnor
Assez juste (je suis heureux d'avoir découvert cette fonction malgré tout). Pouvez-vous clarifier cela dans le PO? À l'heure actuelle, il se lit comme "choisissez vos propres étiquettes" (souligné), puis quelques choix possibles ("vous pouvez ...").
Greg Martin
1
Oh, je vois comment tu le lis; désolé de ne pas être clair ici et de vous avoir conduit sur le mauvais chemin. Permettez-moi d'essayer de le reformuler.
xnor