Czy ten kwadrat jest symetryczny?

22

Napisz program lub funkcję, która pobiera siatkę tekstową 4 × 4 składającą się dokładnie z 4 A, 4 B, 4 Ci 4 D, takich jak:

ACDC
BBCA
BADD
ABCD

W ABCD„S może mieć dowolny układ, ale zawsze będzie 4 każdy. Możesz założyć, że dane wejściowe są prawidłowe. W razie potrzeby możesz również założyć, że ma on końcowy znak nowej linii i / lub że występuje jako jeden wiersz w kolejności czytania, np ACDCBBCABADDABCD. Można również zastąpić znaki ABCDz 0123lub 1234odpowiednio, w razie potrzeby (ale to wszystko).

Wypisuje prawdziwą wartość, jeśli siatka tekstowa ma jakąkolwiek formę symetrii odblaskowej lub obrotowej. Konkretnie:

  • Jeśli istnieje centralna pozioma linia symetrii. na przykład

    BACD
    BACD 
    BACD \___ bottom mirrors top
    BACD /
    
  • Jeśli istnieje centralna pionowa linia symetrii. na przykład

    BCCB
    DAAD
    CAAC
    BDDB
      \/___ right mirrors left
    
  • Jeśli występuje ukośna linia symetrii (w obu kierunkach). na przykład

         ___ diagonally mirrored
        /
    ABDC
    BACD
    DCAB
    CDBA
        \___ diagonally mirrored
    
  • Jeśli występuje symetria obrotowa 90 °. na przykład

    BDAB
    ACCD    same if rotated 90 degrees (or 180 or 270)
    DCCA
    BADB
    
  • Jeśli występuje symetria obrotowa 180 °. na przykład

    DBCA
    BDCA    same if rotated 180 degrees
    ACDB
    ACBD
    

(Pamiętaj, że symetria translacyjna nie wchodzi tutaj w grę.)

Wypisuje wartość fałsz, jeśli siatka nie ma żadnej z wyżej wymienionych symetrii. np. pierwsza przykładowa siatka.

Najkrótszy kod w bajtach wygrywa.

Hobby Calvina
źródło
Czy możemy wziąć listę czterech ciągów jako dane wejściowe?
Martin Ender,
@MartinEnder Tak, w porządku.
Calvin's Hobbies
4
Właśnie to przeczytałem i pomyślałem „nie” lol
Shaun Wild
Gdybyś pomyślał o ułożeniu kwadratu, mógłbyś również wziąć pod uwagę symetrię translacyjną.
Neil,
1
@ Adám Nie. Nie ma więcej formatów wejściowych. Wydaje mi się, że tak naprawdę nie powinienem był pozwolić Martinowi.
Calvin's Hobbies

Odpowiedzi:

16

CJam, 16 bajtów

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

Nienazwany blok, który oczekuje danych wejściowych jako listy czterech ciągów znaków na górze stosu i pozostawia znak 0 (fałsz) dla danych asymetrycznych i dodatnią liczbę całkowitą (prawda) dla danych symetrycznych.

Sprawdź to tutaj. Lub uruchom pełny zestaw testów.

Wyjaśnienie

Symetrie kwadratu są elementami grupy dwuściennej rzędu 8 (które są tylko 4 obrotami kwadratu i takimi samymi 4 obrotami niektórych odbijanych wersji kwadratu). Nie można wygenerować tej grupy po wielokrotnym zastosowaniu pojedynczej permutacji. Ale dwa odbicia zawsze dają pewien obrót. Stąd cała grupa może zostać wygenerowana przez czterokrotne naprzemienne odbicia. (Musimy tylko upewnić się, że dwa odbicia dają obrót o 90 stopni lub 270 stopni, a nie 0 lub 180.)

Wyzwanie polega na pytaniu, czy kwadrat wejściowy jest równy którejkolwiek z pozostałych 7 symetrii. Więc ta odpowiedź generuje je wszystkie, a następnie sprawdza, czy dane wejściowe należą do innych.

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

Aby zobaczyć, w jaki sposób wielokrotne stosowanie zi W%generowanie wszystkich symetrii, spójrz na ten „schemat”:

     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
Martin Ender
źródło
Wow, możesz to wyjaśnić? Czy masz wbudowany do wszystkich obrotów / przerzutów?
Adám,
@ Adám Dodam trochę pełnego wyjaśnienia, ale ztransponuję i W%odwraca linie, więc generuję wszystkie symetrie poprzez ich wielokrotne stosowanie.
Martin Ender,
4
Oczywiście nie ma nic specjalnego w pierwszej wartości, ale niestety bardziej purystyczne podejście polegające na liczeniu, czy otrzymujesz 8 różnych wartości, kosztuje o jeden znak więcej.
Peter Taylor
8

Pyth, 11 bajtów

<7.u?%Y2CN_

Zestaw testowy

To wykorzystuje technikę transpozycji i odwrotności Martina, ale z pewnym zwrotem. Podczas gdy inne rozwiązania wyraźnie wygenerowały wszystkie 8 symetrii, a następnie policzyły liczbę wystąpień oryginału, ten program używa Pyth's.u funkcji .

The .u funkcja to „Zastosuj do znalezienia powtórzenia”. W takim przypadku na przemian dokonujemy transpozycji i cofania do momentu powtórzenia, a następnie gromadzimy wyniki w postaci listy. Następnie usuwam ostatnie 7 wartości, więc pozostanie wartość tylko wtedy, gdy nie będzie symetrii, a pierwsze powtórzenie miało miejsce po wygenerowaniu wszystkich 8 odbić i powtórzeń.

Wyjaśnienie:

<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
isaacg
źródło
5

05AB1E , 13 bajtów

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

Wyjaśnienie

Używa metody fachowo wyjaśnionej przez Martina w odpowiedzi na 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

Wypróbuj online

Emigna
źródło
4

Perl, 61 60 bajtów

Obejmuje +3 za -p0a

Podaj kwadrat wejściowy na STDIN, drukuje 0 dla braku symetrii, w przeciwnym razie pewna liczba dodatnia

./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}{
Ton Hospel
źródło
3

Brachylog , 38 36 bajtów

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

Wypróbuj online!

Oczekuje to listy ciągów jako danych wejściowych. Drukuje albo true.albo false..

Wyjaśnienie

  • Główny predykat:

    @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
    
  • Predykat 1: Wyjście jest jedną z 8 symetrii wejścia.

    (
        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
    )
    
Fatalizować
źródło
3

TSQL, 229 bajtów

Pamiętaj, że TSQL nie ma wbudowanej funkcji obracania, więc jest to zawarte w kodzie.

Gra w golfa:

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

Nie golfowany:

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

Skrzypce

t-clausen.dk
źródło
2

Python 2, 154 146 bajtów

Sprawdza, czy którakolwiek z niezbędnych transformacji jest równoważna oryginałowi za pomocą tablic numpy. Dane wejściowe są traktowane jako lista czterech ciągów.

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

Wypróbuj online

Przyjmowanie danych wejściowych jako pojedynczego ciągu znaków jest dłuższe o jeden znak A=array(list(input())).reshape(4,4). A[:,::-1]jest taki sam jak fliplr(A). A[::-1]jest taki sam jak flipud(A).

mbomb007
źródło
Może map(list,input())zamiast tego użyj[list(r)for r in input()]
Cyoce,
@Cyoce Thanks. Idk, jak mi tego brakowało.
mbomb007,
anyprzyjmuje wyrażenie generatora, dzięki czemu można zaoszczędzić kilka bajtów, upuszczając zewnętrzną parę nawiasów kwadratowych.
TheBikingViking
@ TheBikingViking Próbowałem już tego. Jeśli przekażesz generator, zwróci on generator, dzięki czemu printinstrukcja nie będzie działać. Spróbuj rozwidlić mój kod online i uruchomić go w ten sposób, aby zobaczyć.
mbomb007,
Ach, okej Nie zdawałem sobie sprawy, że to złamie print.
TheBikingViking
2

Python 3, 99 bajtów

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

Funkcja, która pobiera dane wejściowe, za pomocą argumentu, listy ciągów znaków i zwraca Truelub, w Falsezależności od przypadku.

Wykorzystuje takie samo podejście jak @ MartinEnder za odpowiedź .

Jak to działa

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

Wypróbuj na Ideone

TheBikingViking
źródło
2

JavaScript (ES6), 131 bajtów

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 bajtów można usunąć, jeśli przekażesz bezpośrednio tablicę 4 łańcuchów. Próbowałem kręcić bity (wejście w "0123301223011230"formacie), ale zajęło mi to 199 bajtów:

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)
Neil
źródło