[Question]
  [
Takuzu is a logic game in which you have to complete a grid with cells containing `0`s and `1`s. The grid must follow 3 rules:
1. No three horizontal or vertical consecutive cells can be the same.
2. There must be an equal number of `0`s and `1`s in each row and column.
3. No two rows can be the same, and no two columns can be the same.
Let's look at a finished grid:
```
0011
1100
0101
1010
```
As you can see, this board follows rule `1`, `2` and `3`. There are no three horizontal or vertical cells that are the same, all the rows and columns contain an equal number of `0`s and `1`s, and no two rows and no two columns are the same.
Let's look at a grid that isn't valid:
```
110100
010011
011010
101100
100011
001101
```
There's a bunch of problems with this grid. For example, row `5` has three `0`s in a row, and column `2` has three `1`s in a row, followed by three `0`s. Therefore, this is not a valid grid.
## Task:
Your task is to make a program which, given a 2D array of `n` \* `n` `0`s and `1`s, verifies the board to see if it's a valid, finished Takuzu board.
## Examples:
```
0011
1100
0101
1010
```
This board follows all the rules, and is therefore a valid Takuzu board. You must return a truthy value for this.
```
11
00
```
This is not a valid board - row `1` doesn't follow rule `2`. You must return a falsey value for this.
```
100110
101001
010101
100110
011010
011001
```
This is not a valid board, it fails (only) due to rule 3 - the first and fourth rows are the same.
```
110100
001011
010011
101100
100110
011001
```
This is not a valid board, it fails (only) due to rule 3 - the first and fourth columns are the same.
```
011010
010101
101100
010011
100110
101001
```
This is a valid board.
## Rules and Specs:
* You can assume that all boards are square of dimensions `n * n`, where `n` is a positive even integer.
* You can assume that all boards are finished.
* You may take input as a 2D array containing values signifying `0` and `1`, or as a string.
* You must output consistent truthy and falsey values for truthy and falsey boards, and the values representing "truthy" and "falsey" cannot be the same.
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so shortest code in bytes wins!
  
[Answer]
# [Brachylog](https://github.com/JCumin/Brachylog), ~~20~~ 18 bytes
```
≠\≠,?¬{∋s₃=|∋ọtᵐ≠}
```
[Try it online!](https://tio.run/##SypKTM6ozMlPN/r//1Hnghgg1rE/tKb6UUd38aOmZtsaIOPh7t6Sh1snAKVq//@PjjbQMdAx1DGM1YkGkkC2AZBlAGZBxMDs2Nj/AA "Brachylog – Try It Online")
### Explanation
```
≠                           All rows are different
 \                          Transpose
  ≠                         All columns are different
   ,?                       Append the list of rows to the list of columns
     ¬{          }          It is impossible that:
       ∋                      A row/column of the matrix…
        s₃=                   …contains a substring of 3 equal elements
           |                Or that:
            ∋ọ                The occurences of 1s and 0s in a row/column…
              tᵐ≠             …are not equal
```
[Answer]
# [Husk](https://github.com/barbuz/Husk), ~~19~~ 18 bytes
```
S=‼(Tf§=LṁDum(ṁ↑2g
```
[Try it online!](https://tio.run/##yygtzv7/P9j2UcMejZBcjYc7Gx@1TTRK10w7tNzWB8hzKf3//390tIGOgY6hjmGsTjSQBLINgCwDMAsiBmbHxgIA "Husk – Try It Online")
1 byte saved thanks to H.PWiz!
The main idea is applying a series of transformations to the input that are identities for a valid board and checking if the final result is the same as the original input.
### Explanation
```
S=‼(Tf§=LṁDum(ṁ↑2g
            m(ṁ↑2g    in each line, take at most two items for each sequence of equal items
           u          remove duplicate lines
     f§=LṁD          keep only those lines where the sum of each element doubled is equal to the length of the line
    T                 transpose the matrix (swap rows with columns)
  ‼                   do all the previous operations again
S=                    check if the final result is equal to the original input
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 17 bytes
```
-*S;E3Ƥ€F$TȯQZµ⁺⁼
```
[Try it online!](https://tio.run/##y0rNyan8/19XK9ja1fjYkkdNa9xUQk6sD4w6tPVR465HjXv@//8fHW2gY6BjqGMYqxMNJIFsAyDLAMyCiIHZsbEA "Jelly – Try It Online")
-6 bytes thanks to [miles](https://codegolf.stackexchange.com/users/6710/miles) and [Jonathan Allan](https://codegolf.stackexchange.com/users/53748/jonathan-allan).
[Answer]
# Mathematica, 143 bytes
```
And@@Flatten@(((s=#;Equal@@(Count[s,#]&/@{0,1})&&FreeQ[Subsequences@s,#]&/@{{1,1,1},{0,0,0}})&/@#)&&(DeleteDuplicates@#==#)&/@{#,Transpose@#})&
```
  
**input**
> 
> [{{0, 0, 1, 1}, {1, 1, 0, 0}, {0, 1, 0, 1}, {1, 0, 1, 0}}]
> 
> 
> 
[Answer]
# [Python 2](https://docs.python.org/2/), 127 bytes
```
a=input()
n=len(a)
b=zip(*a)
print[n/2]*n*2==map(sum,a+b)>len(set(a))==len(set(b))==n<'0, 0, 0'not in`a+b`>'1, 1, 1'not in`a+b`
```
[Try it online!](https://tio.run/##TYvBCsMgEETv@Qpvunah6rmbHwmBGAhUaDbSmEP783ZNKRSG4c0wk1/lvnGoNVLifBQDHdNjYROhm@mdsrFC@Zm4DHwNo2UbiNaYzX6sGC8z9G29L0UeQPQLcwt80w5Vk@atqMSTHKZee1RN/2Wtg3Ho0KMHNOLCTsid9O1OhvED "Python 2 – Try It Online")
Reads a list of *n* *n*-tuples as input.
I could output by exit code by writing `1/(…)` instead of `print…` but it feels scummy. Should I?
## Explanation
`n` is the size of the board; `b` is a list of columns (transpose of `a`). The rest is one long chained comparison:
* `[n/2]*n*2==map(sum,a+b)` checks rule 2. Each row and column should sum to n/2.
* `map(sum,a+b)>len(set(a))` is always true (list > int).
* `len(set(a))==len(set(b))==n` checks rule 3.
* `n<'0, 0, 0'` is always true (int < str).
* `'0, 0, 0'not in`a+b`>'1, 1, 1'not in`a+b`` checks rule 1. ``a+b`` is the string representation of all the rows and columns; for the example input on TIO it is
```
"[(0, 0, 1, 1), (1, 1, 0, 0), (0, 1, 0, 1), (1, 0, 1, 0), (0, 1, 0, 1), (0, 1, 1, 0), (1, 0, 0, 1), (1, 0, 1, 0)]"
```
The ``a+b`>'1, 1, 1'` in the center is always true since this string is guaranteed to start with `"["`, which is greater than `"1"`.
[Answer]
# [Husk](https://github.com/barbuz/Husk), ~~27~~ 25 bytes
```
Λ§&Λȯ¬VEX3§&Λ§=#0#1S=uSeT
```
Input is a list of lists and output is `1` for `True` and `0` for `False`
[Try it online!](https://tio.run/##yygtzv7//9zsQ8vVzs0@sf7QmjDXCGMw59ByW2UDZcNg29Lg1JD///9HRxvoGOgY6hjG6kQDSSDbAMgyALMgYmB2bCwA "Husk – Try It Online")
### Explaination
```
                      SeT    Create a list with the input and itself transposed
Λ                            Is the following function true for all in the list
 §&                          And the results of the following functions
   Λȯ¬VEX3                     Test for rule 1
          §&                   The and of:
            Λ§=#0#1                Test for rule 2
                   S=u             Test for rule 3
```
### Test 1
```
Λȯ¬VEX3
Λ         Is it True for all ...
   V      Are any of the ...
     X3   Substrings of length 3 ...
    E     All equal
 ȯ¬       Logical not
```
### Test 2
```
Λ§=#0#1
Λ         Is it true for all that ...
 §=       The results of the two functions are equal
   #0         Number of 0s
     #1       Number of 1s
```
### Test 3
```
S=u
S=    Is the result of the following function equal two its argument
  u   Remove duplicates
```
[Answer]
# [Retina](https://github.com/m-ender/retina), ~~129~~ ~~89~~ 85 bytes
```
.+
$&,$&
O#$`.(?=.*,)
$.%`
.+
$&;$&
+`(01|10)(?=.*;)
1ms`(.)\1\1|\d,?;|(\D\d+\b).*\2
```
[Try it online!](https://tio.run/##HckxDoMwDEbh3ddoQHESWf67RhVL917AQ6hgYIChMObuacTy9KTvt17bMbcmkdyY3Eifhyvip5eExORkKHRT7hSLV1Qo35yZCPtZvLDBUG1JU67e3rZE@7IEe7amChCgSgrt1/sH "Retina – Try It Online") Outputs 0 for valid, 1 for invalid. Edit: Saved 4 bytes thanks to @MartinEnder. Explanation:
```
.+
$&,$&
```
Duplicate each row with `,` separators.
```
O#$`.(?=.*,)
$.%`
```
Transpose the first duplicate.
```
.+
$&;$&
```
Duplicate again, this time with `;` separators.
```
+`(01|10)(?=.*;)
```
Delete all matching pairs of digits that precede a semicolon.
```
1ms`(.)\1\1|\d,?;|(\D\d+\b).*\2
```
Check to see whether any column or row fails any of the rules; `(.)\1\1` checks for three identical digits in a row, `\d,?;` checks for an unpaired digit and `(\D\d+\b).*\2` checks for a duplicate.
[Answer]
# [Pyth](https://pyth.readthedocs.io), 31 bytes
Thanks a lot to [@Leaky Nun](https://codegolf.stackexchange.com/users/48934/leaky-nun).
```
.Asm++mqy/k\0lQdm<hk3srL8d{Id,C
```
**[Verify all the test cases](https://pyth.herokuapp.com/?code=.Asm%2B%2Bmqy%2Fk%5C0lQdm%3Chk3srL8d%7BId%2CC&input=%5B%220011%22%2C%221100%22%2C%220101%22%2C%221010%22%5D&test_suite=1&test_suite_input=%5B%220011%22%2C%221100%22%2C%220101%22%2C%221010%22%5D%0A%5B%220011%22%2C%221100%22%2C%220101%22%2C%221010%22%5D%0A%5B%2211%22%2C%2200%22%5D%0A%5B%22110100%22%2C%22010011%22%2C%22011010%22%2C%22101100%22%2C%22100011%22%2C%22001101%22%5D&debug=0) or [Try it here!](https://pyth.herokuapp.com/?code=.Asm%2B%2Bmqy%2Fk%5C0lQdm%3Chk3srL8d%7BId%2CC&input=%5B%220011%22%2C%221100%22%2C%220101%22%2C%221010%22%5D&test_suite_input=%5B%220011%22%2C%221100%22%2C%220101%22%2C%221010%22%5D%0A%5B%220011%22%2C%221100%22%2C%220101%22%2C%221010%22%5D%0A%5B%2211%22%2C%2200%22%5D%0A%5B%22110100%22%2C%22010011%22%2C%22011010%22%2C%22101100%22%2C%22100011%22%2C%22001101%22%5D&debug=0)**
---
# [Pyth](https://pyth.readthedocs.io), ~~48 46 44~~ 42 bytes
This is the initial solution.
```
&{IQ&{I.TQ.Am&q/d\0/d\1!+/d*3\0/d*3\1sC,.T
```
**[Verify all the test cases](https://pyth.herokuapp.com/?code=%26%7BIQ%26%7BI.TQ.Am%26q%2Fd%5C0%2Fd%5C1%21%2B%2Fd%2a3%5C0%2Fd%2a3%5C1sC%2C.T&input=%5B%220011%22%2C%221100%22%2C%220101%22%2C%221010%22%5D&test_suite=1&test_suite_input=%5B%220011%22%2C%221100%22%2C%220101%22%2C%221010%22%5D%0A%5B%220011%22%2C%221100%22%2C%220101%22%2C%221010%22%5D%0A%5B%2211%22%2C%2200%22%5D%0A%5B%22110100%22%2C%22010011%22%2C%22011010%22%2C%22101100%22%2C%22100011%22%2C%22001101%22%5D&debug=0) or [Try it here!](https://pyth.herokuapp.com/?code=%26%7BIQ%26%7BI.TQ.Am%26q%2Fd%5C0%2Fd%5C1%21%2B%2Fd%2a3%5C0%2Fd%2a3%5C1sC%2C.T&input=%5B%220011%22%2C%221100%22%2C%220101%22%2C%221010%22%5D&test_suite_input=%5B%220011%22%2C%221100%22%2C%220101%22%2C%221010%22%5D%0A%5B%220011%22%2C%221100%22%2C%220101%22%2C%221010%22%5D%0A%5B%2211%22%2C%2200%22%5D%0A%5B%22110100%22%2C%22010011%22%2C%22011010%22%2C%22101100%22%2C%22100011%22%2C%22001101%22%5D&debug=0)**
```
&{IQ&{I.TQ.Am&q/d\0/d\1!+/d*3\0/d*3\1sC,.T     Full program with implicit input.
 {IQ                                           Is the input invariant under deduplicating?
&    {I.TQ                                     And is its transpose invariant too?
                                        .TQ    Transpose.
                                           Q   The input.
                                     sC,       Zip the above, [^, ^^] (and flatten).
    &                                          And is the following condition met?
          .Am                                  All elements are truthy when mapping over ^^.
              q/d\0/d\1                        There are as many 0s as 1s.
             &         !+/d*3\0/d*3\1          And there are no runs of 3 equal elements.
```
[Answer]
# [MATL](https://github.com/lmendo/MATL), 27 bytes
```
,G@?!]tEqts~w7BZ+|3<bXBSdvA
```
Input is a matrix containing `0` and `1`. Output is `0` for falsy, `1` for truthy.
[**Try it online!**](https://tio.run/##y00syfn/X8fdwV4xtsS1sKS4rtzcKUq7xtgmKcIpOKXM8f//aEMFQwUDMDawhjGApCGEA5WzhjKgyiCK4MrgCmMB) Or see test cases: [**1**](https://tio.run/##y00syfn/X8fdwV4xtsS1sKS4rtzcKUq7xtgmKcIpOKXM8f//aAMFAwVDBUNrEAFkGliD@QYQETAzFgA), [**2**](https://tio.run/##y00syfn/X8fdwV4xtsS1sKS4rtzcKUq7xtgmKcIpOKXM8f//aEMFQ2sFAwWDWAA), [**3**](https://tio.run/##y00syfn/X8fdwV4xtsS1sKS4rtzcKUq7xtgmKcIpOKXM8f//aEMFQwUDMDawhjGApCGEA5WzhjKgyiCK4MrgCmMB), [**4**](https://tio.run/##y00syfn/X8fdwV4xtsS1sKS4rtzcKUq7xtgmKcIpOKXM8f//aEMFQwUDMDawBhFQrqE1TBTCgYpClMHFIXoMYQKxAA), [**5**](https://tio.run/##y00syfn/X8fdwV4xtsS1sKS4rtzcKUq7xtgmKcIpOKXM8f//aAMFQyAEkQbWEAqCraFMEAmXAQtYI5ggGUOEXCwA).
### Explanation
```
,       % Do twice. First iteration will use the input, second its transpose
  G     %   Push input
  @     %   Push iteration index: first 0, then 1
  ?     %   If nonzero
    !   %     Transpose
  ]     %   End
  t     %   The top of the stack contains the input or its transpose. Duplicate
  Eq    %   Convert to bipolar form, i.e. replace 0 by -1
  t     %   Duplicate
  s     %   Sum of each column
  ~     %   Negate. If all results are true, condition 2 is fulfilled
  w     %   Swap. Moves copy of bipolar input/transposed input to top
  7B    %   Push [1 1 1], obtained as 7 converted to binary
  Z+    %   2D convolution. Gives a matrix of the same size as the input
  |3<   %   Is each entry less than 3 in absolute value? If all results are true,
        %   condition 1 is fulfilled
  b     %   Bubble up. Moves copy of input/transposed input to top
  XB    %   Convert each row from binary to a number
  Sd    %   Sort, consecutive differences. If all results are nonzero, condition 3
        %   is fulfilled
  v     %   Concatenate all results so far into a column vector
  A     %   True if all entries are nonzero
        % End (implicit). Display (implicit)
```
[Answer]
# [R](https://www.r-project.org/), ~~114~~ 107 bytes
*-7 thanks to Giuseppe, calling functions out of order and really compressing the conditions down*
```
function(x)any(f(x),f(t(x)))
f=function(x)c(apply(x,1,function(y)max(rle(y)$l)>2+mean(y)-.5),duplicated(x))
```
[Try it online!](https://tio.run/##ZU/LDsIgELz3Kzh42I3UtEQ9WW/@gNGzofSRJhQa0sb265GmKlRDYJnZZWYwtianmNhqUKJvtIIRuZqgcpVW0LuCGFVZ0BbAu05OMNKUfukJWz6CkaW7bSSe2bYt@UzHuwPSYuhkI3hfFrOerbUuHrnmppitW96bZgQBCU2c5LISuqDkjdxGSpTQMttTkk9GP7Pb9X7BKOdvrXQl9vOIBYPsb9C7eO8169MEiYIz/RgdMYpq8D9Eh3zEFWJoXw "R – Try It Online")
This just applies the rules to the columns of the matrix, then the columns of the transpose of the matrix.
Takes input in the form:
```
matrix(c(0,0,1,1,1,1,0,0,0,1,0,1,1,0,1,0), ncol=4)
```
Which is just how R takes 2D arrays.
Outputs TRUE for failures, FALSE for passes.
[Answer]
# [Perl 6](https://perl6.org), ~~100~~ 93 bytes
*Junctions FTW! They save 7 bytes.*
For the time being, this seems to be beating all the other submissions written in non-golfy languages. Yippie!
```
{!max (@(.map(*.join)).&{.repeated| |.map:{$_~~/000|111/|.comb(0)-.comb(1)}}for @^a,[Z] @^a)}
```
[Try it online!](https://tio.run/##VY3PDoIwDIfvPkVNiFkNju7iQZHwHBo1U0eCcULQg4bBq0/GxD@X9kv7/dpSVZe51U8IMljZeqzlA1jKuJYlm/JzkV8R@aTmlSqVvKuTAeN2izrYt21EREYIERl@LPSBEc48CGyarKgg3clws966jo1djm7SPWIsJiAQIJIw7mrH1BH15Gc9J4g/ES/@y8ORvr9DQ3wwvfc1P647b18 "Perl 6 – Try It Online")
**Explanation**: It's a block that takes the board as list of lists. We make a transpose with `[Z] @^a` (reduce the list of lists with zip operator). So `@^a,[Z] @^a` is a list of the board and its transpose. We loop over it with `for` which works exactly like `map`, just being 1 char cheaper in this case.
Inside, we first join the lists constituting rows into strings, so we have list of strings instead of list of lists (`@(.map(*.join))`). Then we use an anonymous block on it (`.&{...}`), where we actually evaluate the rules. We'll evaluate them only row-wise. (Since we do it for the original array and the transpose as well.)
To save quite some `!`'s, we use a bit of logic and instead of testing `(NO repeated rows) AND (NO 3 consecutive same symbols) AND (NOT different counts of 0 and 1)`, we test `NOT[ (repeated rows) OR (3 consecutive same symbols) OR (different counts) ]`. That's what we do in the anonymous block: `.repeated` gives all rows that occur more than once, then we map over the rows, try to match 3 consecutive symbols using a regex, and subtract the counts of 0's and 1's. These are OR'red with the `|`. (Actually it creates a very powerful thing called a *junction*, but we don't use any of its powers :)) After all of this, we get a list of 2 "bools" (uncollapsed junctions). We finally or them (using `max`) and negate (`!`), which gives the desired result.
[Answer]
# J, ~~40~~ ~~38~~ 55 bytes
```
0=[:([:+/^:_(3(0=3|+/)\"1 ]),:-.@~:,:#=[:+/"1+:@])|:,:]
```
[Try it online!](https://tio.run/##y/r/P03BVk/BwDbaSiPaSls/zipew1jDwNa4RltfM0bJUCFWU8dKV8@hzkrHStkWpELJUNvKIVazBigQy5UH0mwGhCoKhkBoAMYGcBomBpNB8JBVoqjlygUZaQKEKnBhQxRj4cZx5YOUGgEhzHYDrtTkjHyFPAiVppCn4Oekp1CckV@ak6KQlAqTz4XJ56LJG0Ik8mHy@ej6//8HAA)
Defines a function taking a square matrix as input.
~~At least it's beating Pyth (for now...)~~ (erroneously). I should go back to counting the emoji hidden in my code since J also lends itself well to that:
`[:` `/^:` `:1` `|:` `:]` `:-.@` `:#` `:@]` `:~@`
# Explanation (slightly outdated)
This looks different from my answer, and I may get to updating it. Parts of it are still the same -- I just was not checking for rule 3 for and improperly checking for rule 2 before.
Split into a few functions and ungolfed:
```
join_trans  =. |: ,: ]
part_3      =. 3 (0 = 3 | +/)\"1 ]
f           =. 1 - 2 * ]
main        =. 0 = [: ([: +/^:_ part_3 , f) join_trans
```
# join\_trans
```
|: ,: ]
|:       Transpose
   ,:    Laminated to
      ]  Input
```
This joins the transpose of the matrix to itself, creating an array of matrices.
# part\_3
```
3 (0 = 3 | +/)\"1 ]
                  ]  Input (matrix and transpose)
```
This checks the sum of partitions of 3 row-wise to see if it is 3 or 0 (since either of these means an invalid board), returning 1 if it is and 0 otherwise. It operates on both the matrix and its transpose since it's given both.
# f
```
1 - 2 * ]
```
For lack of a better name, I call this `f`. It replaces the 0s with \_1 and leaves the 1s unchanged. This is to allow me to eventually check if the number of 0s and 1s are equal in each row and column (the sum of each of the rows should be 0).
### main
```
0 = [: ([: +/^:_ part_3 , f) join_trans
                             join_trans  Join transpose to input
                 part_3 , f              Apply the validity checks and join them
           +/^:_                         Sum until it converges
0 =                                      Equate to 0
```
Basically, I leverage the fact that I've set it up so that `f join_trans` and `part_3 join_trans` both should sum to 0 iff the board is valid. `part_3` should be all zeroes for a valid board and the entirety of `f` should sum to zero for a valid board, meaning that the sum of their sums is 0 only for a valid board.
[Answer]
# [Haskell](https://www.haskell.org/), ~~137~~ ~~136~~ 127 bytes
*9 bytes saved thanks to Lynn!*
```
import Data.List
j=isSubsequenceOf
l x=x==nub x&&and[sum y*2==length x&&not(j[0,0,0]y||j[1,1,1]y)|y<-x]
g x=l x&&l(transpose x)
```
[Try it online!](https://tio.run/##JYyxDsIgFEX3fgWDaVqDpjrL5mji4EgYqGJLpa@1PBJI@u9YMHc5ubnn9tJ@lDEx6nGeFiRXifJ40xaLgWn7cK1VX6fgqe7vwhDPPGPgWuLLUsKLWzeSsD8zZhR02KcaJqwG3tAtIqzrwE90iwj1Gi4HL4puOzFpaCpcJNh5sor4Oo5SA5sXDbjrePaTRrOevihvMv27zELEHw "Haskell – Try It Online")
[Answer]
# Java 8, ~~350~~ ~~326~~ ~~325~~ ~~312~~ ~~303~~ ~~299~~ ~~298~~ ~~259~~ 255 bytes
```
int r,z,c,p,i,j,k,d,u,v=1;int c(int[][]b){v(b);k=v-=u=1;v(b);return r;}void v(int[][]b){String m="",x;for(d=b.length;j<d|k<d;k+=u,j+=v,r=m.contains(x)|z!=0?1:r,m+=x)for(x="#",c=0,k*=u,j*=v;j<d&k<d;z+=i|i-1,c*=i^p^1,x+=p=i,r=++c>2?1:r,k+=v,j+=u)i=b[k][j];}
```
Returns `0` when it's a valid board; `1` if it's invalid for one or more of the three rules.
-95 bytes thanks to *@Nevay*.
**Explanation:**
[Try it here.](https://tio.run/##xVVNj5swEL3vr3BTqcJhgnCP9U77C3raI2IlMOzWED4EhtIk/PbUkDRiN@DmkKoHsOx58@bNhyEJ2mBTlHGeROlRbIO6Jt8Dme@PMlekgh0IKEFCAilE0ECLjA8WYem353t@SPetFVKeYrvBRlvHXRWrpspJxfu2kBFpJ@gnVcn8lWS4WkHHX4rKijB0tnH@qn7w5DE6pI8RT21sILGxhQozRxS50ppqq6OH3Qd0v7EvFWQ2dnRw73D1cQUCXUjXg9ca24Hn08Czs1Ee5IaBWKN8Lp8ZdDaWKDWtbYuvn0emdIijgzVUYuilvpf4vD/yB0LKJtxKQWoVKL2MqWRaiHXKwfNJQPcaRsjTr1rFmVM0yim1SW1zK49/jpW0qCPGzbkEJwdCLkd7F1xgwHq4suhTbXNnLO5omfcZbX1PKb@HtrMGYGCOOUWyWc1T1B@VYIx4XpeznGpbrtLluU3XMhd7izPomuCMui7KTv36X8P0N5/7DBNbKOwd@Q2tmTTG2N7ltpqabmK@cN8tz@mAmUb7/TAyQ6dnsYszcYU11/Sm6FdYQ/R32Nsu7A3RzR@Bq5obp20Ga56PN5X/l3du8oPoH/rjbw)
```
int r,z,c,p,i,j,k,d,u,v=1;
                     // Temp integers on class-level
int c(int[][]b){     // Method (1) with int-matrix parameter and int return-type
  v(b);              //  Validate the rows
  k=v-=u=1;          //  Switch rows with columns, and reset `u` to 1
  v(b);              //  Validate the columns
  return r;          //  Return the result
}                    // End of method (1)
void v(int[][]b){    // Separated method (2) with int-matrix parameter and no return-type
  String m="",s;     //  Two temp Strings to validate uniqueness of rows
  for(d=b.length;    //  Set the dimension of the matrix to `d`
      j<d|k<d        //  Loop (1) as long as either `j` or `k` is smaller than `d`
    ;                //   After every iteration:
     k+=u,j+=v       //    Increase the loop-indexes
     r=m.contains(s) //    If we've found a duplicated row,
     |z!=0?          //    or if the amount of zeroes and ones on this row aren't equal
      1:r,           //     Set `r` to 1 (invalid due to either rule 2 or 3)
     m+=s)           //    Append the current row to the String `m`
    for(s=",",       //   Set String `x` to a separator-character
        c=0,         //   Reset the counter to 0
        k*=u,j*=v,   //   Increase the loop-indexes
        j<d&k<d      //   Inner loop (2) as long as both `j` and `k` are smaller than `d`
     ;               //    After every iteration:
      z+=i|i-1,      //     Increase or decrease `z` depending on whether it's a 0 or 1
      c*=i^p^1,      //     Reset `c` if current digit `i` does not equal previous `p`
      s+=p=i,        //     Set previous `p` to current digit, and append it to String `s`
      r=++c>2?       //     If three of the same adjacent digits are found:
         1:r;        //      Set `r` to 1 (invalid due to rule 1)
        k+=v,j+=u)   //      Increase the loop-indexes
      i=b[k][j];     //    Set `i` to the current item in the matrix
                     //   End of inner loop (2) (implicit / single-line body)
                     //  End of loop (2) (implicit / single-line body)
}                    // End of separated method (2)
```
[Answer]
# Python 3, 187 bytes
```
lambda m,c=lambda m:all([len({*m})==len(m),sum(~-("000"in x)*~-("111"in x)and x.count("1")==x.count("0")for x in m)==len(m)]):c(["".join(x[i]for x in m)for i in range(len(m[0]))])and c(m)
```
[Try it online!](https://tio.run/##hVBBbsMgELz7FYhLICLRot4skY8QDsRxWyqDI9uRHFXN191diK3eeoEZZoYduD2mzz69Ld6cl87Hy9WzqBqzwtp3nbBdm8T3Pv5IYwhGqcZ7FM@D4ADAQ2Kz3BPTWhfm05XNx6a/pwlPOeY2Bly@9wObGRrjdqGTdSMs58evPiQx2@D@mAgGgoNPH63ICQtOYooGNZhfpnacRmaYtdgJaygsg90UBw2Z4c6d@k/NGqwYNlMJQT4q/iLh@pKyVnIvz@bQ6yDnqooeQ2XpPbl0XbHbEPBriKnd4bRTPmMpl18 "Python 3 – Try It Online")
Takes input as a list of lines.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 29 bytes
```
ø‚D€ÙQIDøì©O·IgQP®εŒ3ù€Ë_P}PP
```
[Try it online!](https://tio.run/##MzBNTDJM/f//8I5HDbNcHjWtOTwz0NPl8I7Daw6t9D@03TM9MODQunNbj04yPrwTJNsdH1AbEPD/f3S0gY4CEBkCUayOQrQhmAkSA/EMYDyYHFQgNhYA "05AB1E – Try It Online")
**Explanation**
Rule: 3
```
ø‚        # pair the input with the zipped input
  D       # duplicate
   €Ù     # deduplicate each
     Q    # check for equality with the unmodified copy
```
Rule: 2
```
IDøì          # prepend zipped input to input
    ©         # store a copy in register for rule 1
     O        # sum each row/column
      ·       # double
       IgQ    # check each for equality to length of input
          P   # product
```
Rule: 1
```
®ε            # apply to each row/column in register
  Œ3ù         # get sublists of length 3
     €Ë       # check each if all elements are equal
       _      # logical not
        P     # product
         }    # end apply
          P   # product
```
Then we take the product of the result of all 3 rules with `P` 
[Answer]
# Dyalog APL, ~~64~~ ~~52~~ ~~51~~ ~~49~~ 48 bytes
Requires `⎕IO←0`
```
{⍲/{(∨/∊⍷∘⍵¨3/¨⍳2)∧((⊢≡∪)↓⍵)∧∧/(≢=2×+/)⍵}¨⍵(⍉⍵)}
```
[Try it online!](https://tio.run/##TY7BCoJAFEX38xXuHAsbM1q2VVr1DWIQgVDgKsStjMJIEFHb3CQtK2lvf3J/xN5Yi4bH3PfOfZeZYBvZy10QbVZ2GAVxvA67DuVxvkC2dxjzSBKou0g4ZC0gC6gX5BmqaeuJaGuoh2tBXjlHUSG/QN4sZAfyNaUSHHk1c9@nobCIpjrScKhcr6TM/z5Q9hjqCVW7YjQdkFJOBxij/9CWZ/iG6ThjOg4JNXSZ/2ZPtNV7eujlC3/UZF33AQ)
[Answer]
# PHP, 245+1 bytes
ew this is bulky. linebreaks are for reading convenience only:
```
$t=_;foreach($a=($i=str_split)($s=$argn)as$i=>$c)$t[$i/($e=strlen($s)**.5)+$i%$e*$e]=$c;
for(;$k++<2;$s=$t)$x|=preg_match("#000|111|(\d{"."$e}).*\\1#s",chunk_split($s,$e))
|($m=array_map)(array_sum,$m($i,$i($s,$e)))!=array_fill(0,$e,$e/2);echo!$x;
```
Takes a single string without newlines, prints `1` for truthy, nothing for falsy.
Run as pipe with `-nR` or [try it online](http://sandbox.onlinephpfunctions.com/code/eac9d0ceb8dfae6fbcb1aebec4cb43a08b09ea41).
]