Ist das Quadrat symmetrisch?


22

Schreiben Sie ein Programm oder eine Funktion, die ein 4 × 4-Textraster enthält, das aus genau 4 A, 4 B, 4 Cund 4 besteht D, wie z.

ACDC
BBCA
BADD
ABCD

Die ABCDkönnen in jeder Anordnung sein, aber es werden immer 4 von jedem sein. Sie können davon ausgehen, dass die Eingabe gültig ist. Auf Wunsch können Sie auch davon ausgehen, dass es sich um eine nachgestellte Zeile handelt und / oder dass es sich um eine einzelne Zeile in Lesereihenfolge handelt, z ACDCBBCABADDABCD. Falls gewünscht, können Sie die Zeichen auch ABCDdurch 0123oder ersetzen 1234(aber das ist alles).

Geben Sie einen Wahrheitswert aus, wenn das Textgitter irgendeine Form von Reflexions- oder Rotationssymmetrie aufweist. Speziell:

  • Wenn es eine zentrale horizontale Symmetrielinie gibt. z.B

    BACD
    BACD 
    BACD \___ bottom mirrors top
    BACD /
    
  • Wenn es eine zentrale vertikale Symmetrielinie gibt. z.B

    BCCB
    DAAD
    CAAC
    BDDB
      \/___ right mirrors left
    
  • Wenn es eine diagonale Symmetrielinie gibt (in beide Richtungen). z.B

         ___ diagonally mirrored
        /
    ABDC
    BACD
    DCAB
    CDBA
        \___ diagonally mirrored
    
  • Bei 90 ° Rotationssymmetrie. z.B

    BDAB
    ACCD    same if rotated 90 degrees (or 180 or 270)
    DCCA
    BADB
    
  • Bei 180 ° Rotationssymmetrie. z.B

    DBCA
    BDCA    same if rotated 180 degrees
    ACDB
    ACBD
    

(Beachten Sie, dass die translatorische Symmetrie hier nicht ins Spiel kommt.)

Geben Sie einen falschen Wert aus, wenn das Raster keine der oben genannten Symmetrien aufweist. zB das allererste Beispielraster.

Der kürzeste Code in Bytes gewinnt.


Können wir eine Liste von vier Zeichenketten als Eingabe nehmen?
Martin Ender

@ MartinEnder Ja, in Ordnung.
Calvins Hobbys

4
Ich habe das gerade gelesen und dachte "nein" lol
Shaun Wild

Wenn Sie sich überlegt hätten, das Quadrat zu kacheln, hätten Sie auch die translatorische Symmetrie berücksichtigen können.
Neil

1
@ Adám No. Keine Eingabeformate mehr. Ich denke, ich hätte Martins nicht wirklich erlauben sollen.
Calvins Hobbys

Antworten:


16

CJam, 16 Bytes

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

Ein unbenannter Block, der die Eingabe als Liste von vier Zeichenfolgen über dem Stapel erwartet und 0für asymmetrische Eingaben eine (falsy) und für symmetrische Eingaben eine positive Ganzzahl (truthy) zurücklässt.

Teste es hier. Oder führen Sie eine vollständige Testsuite aus.

Erläuterung

Die Symmetrien des Quadrats sind die Elemente der Diedergruppe der Ordnung 8 (die nur die 4 Umdrehungen des Quadrats und die gleichen 4 Umdrehungen einer reflektierten Version des Quadrats sind). Es ist nicht möglich, diese Gruppe durch wiederholtes Anwenden einer einzelnen Permutation zu generieren. Zwei Reflexionen ergeben jedoch immer eine gewisse Rotation. Somit kann die gesamte Gruppe erzeugt werden, indem viermal zwischen zwei Reflexionen gewechselt wird. (Wir müssen nur sicherstellen, dass die beiden Reflexionen eine 90-Grad- oder 270-Grad-Drehung ergeben, nicht 0 oder 180.)

Bei der Abfrage wird gefragt, ob das Eingangsquadrat einer der anderen 7 Symmetrien entspricht. Diese Antwort generiert also nur alle von ihnen und prüft dann, ob die Eingabe unter den anderen ist.

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

Um zu sehen, wie das wiederholte Anwenden zund W%Erzeugen aller Symmetrien erfolgt, schauen Sie sich dieses "Diagramm" an:

     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, kannst du das erklären? Hast du ein eingebautes für alle Drehungen / Flips?
Adám

@Adam Ich werde gleich eine vollständige Erklärung hinzufügen, aber ztransponieren und W%die Linien umkehren, so dass ich nur alle Symmetrien durch wiederholtes Anwenden dieser generiere.
Martin Ender

4
Natürlich hat der erste Wert nichts Besonderes, aber leider kostet der puristischere Ansatz, zu zählen, ob Sie 8 verschiedene Werte erhalten, ein Zeichen mehr.
Peter Taylor

8

Pyth, 11 Bytes

<7.u?%Y2CN_

Testsuite

Dies verwendet Martins Transponierungs- und Umkehrtechnik, jedoch mit einem gewissen Dreh. Während andere Lösungen alle 8 Symmetrien explizit generiert und dann die Anzahl der Erscheinungsbilder des Originals gezählt haben, verwendet dieses Programm die Pyth- .uFunktion.

Die .uFunktion ist "Übernehmen bis Wiederholung gefunden". In diesem Fall transponieren und kehren wir abwechselnd um, bis eine Wiederholung auftritt, und akkumulieren dann die Ergebnisse in einer Liste. Dann entferne ich die letzten 7 Werte, sodass nur ein Wert übrig bleibt, wenn keine Symmetrien vorhanden sind, und die erste Wiederholung erfolgt, nachdem alle 8 Reflexionen und Wiederholungen generiert wurden.

Erläuterung:

<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


4

Perl, 61-60 Bytes

Beinhaltet +3 für -p0a

Geben Sie bei STDIN ein Quadrat ein, und geben Sie 0 aus, wenn keine Symmetrie vorliegt. Andernfalls wird eine positive Zahl ausgegeben

./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 Bytes

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

Probieren Sie es online!

Dies erwartet eine Liste von Zeichenfolgen als Eingabe. Dies druckt entweder true.oder false..

Erläuterung

  • Hauptprädikat:

    @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ädikat 1: Die Ausgabe ist eine der 8 Symmetrien der Eingabe.

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

Beachten Sie, dass TSQL kein integriertes Programm zum Drehen hat. Daher ist dies im Code enthalten.

Golf gespielt:

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

Ungolfed:

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

Geige


2

Python 2, 154 146 Bytes

Überprüft mithilfe von Numpy-Arrays, ob eine der erforderlichen Transformationen dem Original entspricht. Die Eingabe wird als Liste von vier Zeichenfolgen verwendet.

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

Probieren Sie es online aus

Die Eingabe als einzelne Zeichenfolge ist mit ein Zeichen länger A=array(list(input())).reshape(4,4). A[:,::-1]ist das gleiche wie fliplr(A). A[::-1]ist das gleiche wie flipud(A).


Vielleicht verwenden Sie map(list,input())anstelle von[list(r)for r in input()]
Cyoce

@Cyoce Danke. Idk wie ich das verpasst habe.
mbomb007

anyNimmt einen Generatorausdruck an, sodass Sie einige Bytes sparen können, indem Sie das äußere Paar eckiger Klammern entfernen.
TheBikingViking

@TheBikingViking Das hatte ich schon probiert. Wenn Sie einen Generator übergeben, wird ein Generator zurückgegeben, sodass die printAnweisung nicht funktioniert. Versuchen Sie, meinen Online-Code zu forken und auf diese Weise auszuführen.
mbomb007

Ach ja ok Ich wusste nicht, dass es das brechen würde print.
TheBikingViking

2

Python 3, 99 Bytes

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

Eine Funktion, die über ein Argument eine Liste von Zeichenfolgen eingibt und zurückgibt Trueoder Falsedie relevant ist.

Dies verwendet den gleichen Ansatz wie @ MartinEnder die Antwort .

Wie es funktioniert

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

Probieren Sie es auf Ideone


2

JavaScript (ES6), 131 Byte

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 Bytes könnten entfernt werden, wenn Sie ein Array von 4 Strings direkt übergeben. Ich habe Bit-Twiddling (Eingabe im "0123301223011230"Format) versucht, aber das hat mir 199 Bytes gekostet :

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)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.