[Question]
  [
Write a program or function that takes in a 4×4 text grid consisting of exactly 4 `A`'s, 4 `B`'s, 4 `C`'s, and 4 `D`'s, such as:
```
ACDC
BBCA
BADD
ABCD
```
The `ABCD`'s may be in any arrangement but there will always be 4 of each. You can assume the input is valid. If desired you can also assume it has a trailing newline and/or that it comes as one line in reading order, e.g. `ACDCBBCABADDABCD`. You may also replace the characters `ABCD` with `0123` or `1234` respectively, if desired (but that's all).
Output a truthy value if the text grid has any form of reflective or rotational symmetry. Specifically:
* If there is a central horizontal line of symmetry. e.g.
```
BACD
BACD 
BACD \___ bottom mirrors top
BACD /
```
* If there is a central vertical line of symmetry. e.g.
```
BCCB
DAAD
CAAC
BDDB
  \/___ right mirrors left
```
* If there is a diagonal line of symmetry (in either direction). e.g.
```
     ___ diagonally mirrored
    /
ABDC
BACD
DCAB
CDBA
    \___ diagonally mirrored
```
* If there is 90° rotational symmetry. e.g.
```
BDAB
ACCD    same if rotated 90 degrees (or 180 or 270)
DCCA
BADB
```
* If there is 180° rotational symmetry. e.g.
```
DBCA
BDCA    same if rotated 180 degrees
ACDB
ACBD
```
(Note that translational symmetry doesn't come into play here.)
Output a falsy value if the grid doesn't have one of the symmetries mentioned above. e.g. the very first example grid.
**The shortest code in bytes wins.**
  
[Answer]
## CJam, 16 bytes
```
{{z_W%_}4*;])e=}
```
An unnamed block which expects the input as a list of four strings on top of the stack and leaves a `0` (falsy) for asymmetric inputs and a positive integer (truthy) for symmetric inputs.
[Test it here.](http://cjam.aditsu.net/#code=%5B%22ACDC%22%0A%20%22BBCA%22%0A%20%22BADD%22%0A%20%22ABCD%22%5D%0A%0A%7B%7Bz_W%25_%7D4*%3B%5D)e%3D%7D%0A%0A~) [Or run a full test suite.](http://cjam.aditsu.net/#code=%5B%22ACDCBBCABADDABCD%22%0A%20%22BACDBACDBACDBACD%22%0A%20%22BCCBDAADCAACBDDB%22%0A%20%22ABDCBACDDCABCDBA%22%0A%20%22BDABACCDDCCABADB%22%0A%20%22DBCABDCAACDBACBD%22%0A%20%22ABCDBABDCBACDDCA%22%0A%20%22DDCACBACBABDABCD%22%0A%20%22ABCDDACBDACBABCD%22%0A%20%22ADDABAABCCCCDBBD%22%5D%0A%7B4%2F%0A%0A%7B%7Bz_W%25_%7D4*%3B%5D)e%3D%7D%0A%0A~p%7D%2F)
### Explanation
The symmetries of the square are the elements of the [dihedral group of order 8](http://groupprops.subwiki.org/wiki/Dihedral_group:D8) (which are just the 4 rotations of the square and the same 4 rotations of some reflected version of the square). It's not possible to generate this group from repeated application of a single permutation. But two reflections always give some rotation. Hence, the entire group can be generated by alternating between two reflections four times. (We just need to make sure that the two reflections give the 90 degree or 270 degree rotation, not 0 or 180.)
The challenge asks whether the input square is equal to any of the other 7 symmetries. So this answer just generates all of them and then checks whether the input is among the others.
```
{      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.
```
To see how the repeated application of `z` and `W%` generates all symmetries, have a look at this "diagram":
```
     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
```
[Answer]
# Pyth, 11 bytes
```
<7.u?%Y2CN_
```
[Test suite](https://pyth.herokuapp.com/?code=%3C7.u%3F%25Y2CN_&input=%0A&test_suite=1&test_suite_input=%5B%27ACDC%27%2C+%27BBCA%27%2C+%27BADD%27%2C+%27ABCD%27%5D%0A%5B%22BACD%22%2C+%22BACD%22%2C+%22BACD%22%2C+%22BADC%22%5D%0A%5B%22BCCB%22%2C+%22DAAD%22%2C+%22CAAC%22%2C+%22BDDB%22%5D%0A%5B%22BACD%22%2C+%22BACD%22%2C+%22BACD%22%2C+%22BACD%22%5D%0A%5B%27ABDC%27%2C+%27BACD%27%2C+%27DCAB%27%2C+%27CDBA%27%5D%0A%5B%27BDAB%27%2C+%27ACCD%27%2C+%27DCCA%27%2C+%27BADB%27%5D%0A%5B%27DBCA%27%2C+%27BDCA%27%2C+%27ACDB%27%2C+%27ACBD%27%5D&debug=0)
This uses Martin's transpose and reverse technique, but with a twist. While other solutions have explicitly generated all 8 symmetries, then counted the number of appearances of the original, this program uses Pyth's `.u` function.
The `.u` function is the "Apply until repeat is found". In this case, we alternately transpose and reverse until a repetition happens, then accumulate the results into a list. Then, I remove the last 7 values, so there will only be a value remaining if there were no symmetries, and the first repetition happened after all 8 reflections and repetitions were generated.
Explanation:
```
<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
```
[Answer]
## [05AB1E](https://github.com/Adriandmen/05AB1E/), 13 bytes
```
4Fø€JÂD}\\)¹å
```
**Explanation**
Uses the method expertly explained by [Martin in his CJam answer](https://codegolf.stackexchange.com/a/90218/47066).
```
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
```
[Try it online](http://05ab1e.tryitonline.net/#code=NEbDuOKCrErDgkR9XFwpwrnDpQ&input=WydCREFCJywnQUNDRCcsJ0RDQ0EnLCdCQURCJ10)
[Answer]
# Perl, ~~61~~ 60 bytes
Includes +3 for `-p0a`
Give input square on STDIN, prints 0 for no symmetry, otherwise some positive number
```
./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}{
```
[Answer]
# [Dyalog APL](http://goo.gl/9KrKoM), ~~37~~ ~~19~~ 17 [bytes](http://meta.codegolf.stackexchange.com/a/9429/43319)
@ngn reduced it by 20 bytes!
```
8>≢(∪⊢,⌽¨,⍉¨)⍣≡⊂⎕
```
[TryAPL online!](http://tryapl.org/?a=f%u2190%7B8%3E%u2262%28%u222A%u22A2%2C%u233D%A8%2C%u2349%A8%29%u2363%u2261%u2282%u2375%7D%20%u22C4%20%u22A2squares%u21904%204%u2218%u2374%A8%27ACDCBBCABADDABCD%27%20%27BACD%27%20%27BCCBDAADCAACBDD%27%20%27ABDCBACDDCABCDB%27%20%27BDABACCDDCCABAD%27%20%27DBCABDCAACDBACBD%27%20%u22C4%20f%A8squares&run)
[Answer]
# [Brachylog](https://github.com/JCumin/Brachylog), ~~38~~ 36 bytes
```
@eL:1fbeL
(L;?:raL)(.;L$\.;L$/.;Lr.)
```
[Try it online!](http://brachylog.tryitonline.net/#code=QGVMOjFmYmVMCihMOz86cmFMKSguO0wkXC47TCQvLjtMci4p&input=WyJCREFCIjoiQUNDRCI6IkRDQ0EiOiJCQURCIl0)
This expects a list of strings as input. This prints either `true.` or `false.`.
### Explanation
* Main predicate:
```
@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
```
* Predicate 1: Output is one of the 8 symmetries of the input.
```
(
    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
)
```
[Answer]
# TSQL, ~~229~~ 225 bytes
Be aware TSQL has no build-in for rotating, so this is part the code.
Returning -1 for true 0 for false
**Golfed:**
```
DECLARE @1 char(16)='BCCBDAADCAACBDDB'
DECLARE @i INT=0,@ char(16)=0WHILE @i<16SELECT
@=substring(@1,@i*4%16+@i/4+1,1)+@,@i+=1SELECT~count(*)/2FROM (SELECT
left(x,8)a,right(x,4)b,substring(x,9,4)c
FROM(values(@1),(@))x(x))x
WHERE a in(reverse(b+c),b+c,reverse(c+b))
```
**Ungolfed:**
```
DECLARE @1 char(16)='BCCBDAADCAACBDDB'
DECLARE @i INT=0,@ char(16)=0
WHILE @i<16
  SELECT @=substring(@1,@i*4%16+@i/4+1,1)+@,@i+=1
SELECT~count(*)/2
FROM
  (SELECT left(x,8)a,right(x,4)b,substring(x,9,4)c
   FROM(values(@1),(@))x(x))x
WHERE a in(reverse(b+c),b+c,reverse(c+b))
```
**[Fiddle](https://data.stackexchange.com/stackoverflow/query/1191884/is-this-square-symmetrical)**
[Answer]
# Python 2, ~~154~~ 146 bytes
Checks if any of the necessary transformations is equivalent to the original using numpy arrays. Input is taken as a list of four strings.
```
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))])
```
[**Try it online**](http://ideone.com/bSIQ4D)
Taking input as a single string is one char longer, with `A=array(list(input())).reshape(4,4)`. `A[:,::-1]` is the same as `fliplr(A)`. `A[::-1]` is the same as `flipud(A)`.
[Answer]
# 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
```
A function that takes input, via argument, of a list of strings and returns `True` or `False` as relevant.
This uses the same approach as @MartinEnder's [answer](https://codegolf.stackexchange.com/a/90218/55526).
**How it works**
```
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
```
[Try it on Ideone](http://ideone.com/5ZFFRg)
[Answer]
## JavaScript (ES6), 131 bytes
```
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 could be removed if you pass an array of 4 strings directly. I tried bit-twiddling (input in `"0123301223011230"` format) but that took me 199 bytes:
```
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)
```
]