Ce carré est-il symétrique?


22

Écrivez un programme ou une fonction qui prend dans une grille de texte 4 × 4 composée exactement de 4 A, 4 B, 4 Cet 4 D, tels que:

ACDC
BBCA
BADD
ABCD

Les ABCDpeuvent être dans n'importe quel arrangement mais il y en aura toujours 4 de chaque. Vous pouvez supposer que l'entrée est valide. Si vous le souhaitez , vous pouvez également supposer qu'il a un saut de ligne et / ou qu'il se présente comme une ligne dans l' ordre de lecture, par exemple ACDCBBCABADDABCD. Vous pouvez également remplacer les caractères ABCDpar 0123ou 1234respectivement, si vous le souhaitez (mais c'est tout).

Générez une valeur véridique si la grille de texte présente une forme de symétrie réfléchissante ou rotationnelle. Plus précisément:

  • S'il y a une ligne de symétrie horizontale centrale. par exemple

    BACD
    BACD 
    BACD \___ bottom mirrors top
    BACD /
    
  • S'il y a une ligne de symétrie verticale centrale. par exemple

    BCCB
    DAAD
    CAAC
    BDDB
      \/___ right mirrors left
    
  • S'il y a une diagonale de symétrie (dans les deux sens). par exemple

         ___ diagonally mirrored
        /
    ABDC
    BACD
    DCAB
    CDBA
        \___ diagonally mirrored
    
  • S'il y a une symétrie de rotation de 90 °. par exemple

    BDAB
    ACCD    same if rotated 90 degrees (or 180 or 270)
    DCCA
    BADB
    
  • S'il y a une symétrie de rotation de 180 °. par exemple

    DBCA
    BDCA    same if rotated 180 degrees
    ACDB
    ACBD
    

(Notez que la symétrie translationnelle n'entre pas en jeu ici.)

Générez une valeur fausse si la grille n'a pas l'une des symétries mentionnées ci-dessus. par exemple le tout premier exemple de grille.

Le code le plus court en octets gagne.


Pouvons-nous prendre une liste de quatre chaînes en entrée?
Martin Ender

@MartinEnder Oui, d'accord.
Calvin's Hobbies

4
Je viens de lire ça et j'ai pensé "non" lol
Shaun Wild

Si vous aviez pensé à carreler le carré, vous auriez pu également prendre en compte la symétrie translationnelle.
Neil

1
@ Adám Non. Plus de formats d'entrée. Je pense que je n'aurais pas vraiment dû permettre à Martin.
Calvin's Hobbies

Réponses:


16

CJam, 16 octets

{{z_W%_}4*;])e=}

Un bloc sans nom qui attend l'entrée comme une liste de quatre chaînes au-dessus de la pile et laisse un 0(faux) pour les entrées asymétriques et un entier positif (vrai) pour les entrées symétriques.

Testez-le ici. Ou exécutez une suite de tests complète.

Explication

Les symétries du carré sont les éléments du groupe dièdre d'ordre 8 (qui ne sont que les 4 rotations du carré et les mêmes 4 rotations d'une version réfléchie du carré). Il n'est pas possible de générer ce groupe à partir de l'application répétée d'une seule permutation. Mais deux reflets donnent toujours une rotation. Par conséquent, le groupe entier peut être généré en alternant quatre fois deux réflexions. (Nous devons juste nous assurer que les deux réflexions donnent la rotation de 90 degrés ou 270 degrés, pas 0 ou 180.)

Le défi demande si le carré d'entrée est égal à l'une des 7 autres symétries. Donc, cette réponse les génère tous et vérifie ensuite si l'entrée est parmi les autres.

{      e# Run this block 4 times.
  z_   e# Transpose the grid and duplicate it. (This is one type of reflection.)
  W%_  e# Reverse the lines and duplicate it. (This is another type of
       e# reflection. Together they rotate the grid by 90 degrees.)
}4*    e# The last element will be the original grid again.
;      e# Discard one copy of that original grid.
]      e# Wrap all symmetries in a list.
)      e# Pull off the original grid.
e=     e# Count how many times it appears among the other symmetries.

Pour voir comment l'application répétée de zet W%génère toutes les symétries, jetez un œil à ce "diagramme":

     0123
     4567
     89ab
     cdef

     original

 z   048c       W%       37bf
-->  159d  ----------->  26ae
     26ae                159d
     37bf                048c

     diag. refl.         rot. 90 degrees ccw

 z   3210       W%       fedc
-->  7654  ----------->  ba98
     ba98                7654
     fedc                3210

     vert. refl.        rot. 180 degrees

 z   fb73       W%       c840
-->  ea62  ----------->  d951
     d951                ea62
     c840                fb73

     antidiag. refl.     rot. 270 degrees ccw

 z   cdef       W%       0123
-->  89ab  ----------->  4567
     4567                89ab
     0123                cdef

     horiz. refl.        original

Wow, pouvez-vous expliquer cela? Avez-vous un intégré pour toutes les rotations / flips?
Adám

@ Adám Je vais ajouter une explication complète dans un peu, mais zc'est la transposition et W%inverse les lignes, donc je ne fais que générer toutes les symétries en les appliquant de façon répétée.
Martin Ender

4
Il n'y a, bien sûr, rien de spécial dans la première valeur, mais malheureusement, l'approche plus puriste de compter si vous obtenez 8 valeurs distinctes coûte un char de plus.
Peter Taylor

8

Pyth, 11 octets

<7.u?%Y2CN_

Suite de tests

Cela utilise la technique de transposition et d'inversion de Martin, mais avec une touche. Alors que d'autres solutions ont généré explicitement les 8 symétries, puis compté le nombre d'apparitions de l'original, ce programme utilise la .ufonction de Pyth .

La .ufonction est "Appliquer jusqu'à ce que la répétition soit trouvée". Dans ce cas, nous transposons et inversons alternativement jusqu'à ce qu'une répétition se produise, puis accumulons les résultats dans une liste. Ensuite, je supprime les 7 dernières valeurs, donc il ne restera qu'une valeur s'il n'y avait pas de symétries, et la première répétition s'est produite après que les 8 réflexions et répétitions ont été générées.

Explication:

<7.u?%Y2CN_
<7.u?%Y2CN_NQ    Implicit variables
                 Q = eval(input())
  .u        Q    Starting with Q, apply the following until a repeat occurs, 
                 then accumulate all values into a list.
    ?%Y2         If the iteration number is odd
        CN       Transpose
          _N     Else reverse
<7               Remove the last 7 results

5

05AB1E , 13 octets

4Fø€JÂD}\\)¹å

Explication

Utilise la méthode savamment expliquée par Martin dans sa réponse CJam .

4F     }       # 4 times do:
  ø€J          # zip and join each
     ÂD        # bifurcate, duplicate
        \\     # delete the top 2 items on the stack
          )    # wrap stack in list
           ¹å  # check if input is in that list

Essayez-le en ligne


4

Perl, 61 60 octets

Comprend +3 pour -p0a

Donne le carré d'entrée sur STDIN, imprime 0 pour aucune symétrie, sinon un certain nombre positif

./symmetry.pl
DBCA
BDCA
ACDB
ACBD
^D

symmetry.pl:

#!/usr/bin/perl -p0a
s,.,chop$F[$i++/($j-4?1:4)%4],eg;$\+=$$_++;++$j<8&&redo}{


3

Brachylog , 38 36 octets

@eL:1fbeL
(L;?:raL)(.;L$\.;L$/.;Lr.)

Essayez-le en ligne!

Cela attend une liste de chaînes en entrée. Cela imprime soit true.ou false..

Explication

  • Prédicat principal:

    @eL    Split each line into a list of chars ; call that list of lists L
    :1f    Find all symmetries
    b      Remove the first one (the identity)
    eL     L is an element of that list of symmetries
    
  • Prédicat 1: la sortie est l'une des 8 symétries de l'entrée.

    (
        L             L = Input
    ;             Or
        ?:raL         L = reverse all lines of the input
    )
    (
        .             Output = L
    ;             Or
        L$\.          Output = transpose of L    
    ;             Or
        L$/.          Output = antitranspose of L
    ;             Or
        Lr.           Output = reverse of L
    )
    

3

TSQL, 229 octets

Soyez conscient que TSQL n'a pas de build pour la rotation, donc cela est inclus dans le code.

Golfé:

DECLARE @1 char(16)=
'BCCBDAADCAACBDDB'

,@i INT=0,@ varchar(16)=''WHILE @i<16SELECT @+=substring(@1,@i*4%16+@i/4+1,1),@i+=1SELECT sign(count(*))FROM(SELECT LEFT(x,8)a,RIGHT(x,4)b,substring(x,9,4)c FROM(values(@1),(@))x(x))x WHERE c+b=reverse(a)or a=reverse(b+c)or a=b+c

Non golfé:

DECLARE @1 char(16)=
'BCCBDAADCAACBDDB'

,@i INT=0,@ varchar(16)=''
WHILE @i<16
  SELECT @+=substring(@1,@i*4%16+@i/4+1,1),@i+=1

SELECT sign(count(*))
FROM
  (SELECT LEFT(x,8)a,RIGHT(x,4)b,substring(x,9,4)c
   FROM(values(@1),(@))x(x))x
WHERE c+b=reverse(a)or a=reverse(b+c)or a=b+c

Violon


2

Python 2, 154 146 octets

Vérifie si l'une des transformations nécessaires est équivalente à l'original à l'aide de tableaux numpy. L'entrée est considérée comme une liste de quatre chaînes.

from numpy import*
A=array(map(list,input()))
R=rot90
T=transpose(A)
print any([all(A==Z)for Z in(A[:,::-1],A[::-1],R(A),R(A,2),R(A,3),T,R(T,2))])

Essayez-le en ligne

Prendre l'entrée comme une seule chaîne est un caractère de plus, avec A=array(list(input())).reshape(4,4). A[:,::-1]est le même que fliplr(A). A[::-1]est le même que flipud(A).


Peut-être utiliser à la map(list,input())place de[list(r)for r in input()]
Cyoce

@Cyoce Merci. Idk comment j'ai raté ça.
mbomb007 du

anyprend une expression de générateur, vous pouvez donc économiser quelques octets en supprimant la paire extérieure de crochets.
TheBikingViking

@TheBikingViking J'avais déjà essayé ça. Si vous passez un générateur, il retourne un générateur, ce qui rend l' printinstruction ne fonctionne pas. Essayez de bifurquer mon code en ligne et de l'exécuter de cette façon pour voir.
mbomb007

Ah ok. Je ne savais pas que cela briserait le print.
TheBikingViking

2

Python 3, 99 octets

def f(x):
 t=x;c=[]
 for i in range(7):*t,=[map(''.join,zip(*t)),t[::-1]][i%2];c+=t,
 return x in c

Une fonction qui prend en entrée, via un argument, une liste de chaînes et retourne Trueou Falseselon le cas.

Cela utilise la même approche que la réponse de @ MartinEnder .

Comment ça marche

def f(x)                Function with input list of strings x
 t=x;c=[]               Initilaise temporary square t and combination list c
 for i in range(7):...  For i in range [0,6]:
 [...][i%2]              If i is even:
 zip(*t)                  transpose(t)
 *t,=map(''.join,...)     t = t with each line concatenated (such that t is in the same
                          format as x)
                         Else:
 *t,=t[::-1]              t = reverse(t)
 c+=t,                   Append t to c
 return x in c           Return True if x is in c else return False

Essayez-le sur Ideone


2

JavaScript (ES6), 131 octets

s=>[...`0101010`].map(c=>+c?``+b.reverse():`${b=b.map((s,i)=>s.replace(/./g,(_,j)=>b[j][i]))}`,b=a=s.match(/..../g)).includes(``+a)

17 octets pourraient être supprimés si vous passez directement un tableau de 4 chaînes. J'ai essayé le bit-twiddling (entrée au "0123301223011230"format) mais cela m'a pris 199 octets:

s=>[...'0101010'].map(c=>r=+c?r<<24&255<<24|r<<8&255<<16|r>>8&255<<8|r>>>24:r&0xc0300c03|r<<6&806093568|r<<12&3075<<16|r<<18&3<<24|r>>6&0xc0300c|r>>12&49200|r>>18&192,r=n=parseInt(s,4)|0).includes(n)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.