| Bytes | Lang | Time | Link |
|---|---|---|---|
| 015 | APLNARS | 250108T194922Z | Rosario |
| 051 | Google Sheets | 240708T191207Z | doubleun |
| 007 | Jelly | 250107T230506Z | lolad |
| 038 | Raku Perl 6 rakudo | 240813T043333Z | bb94 |
| 102 | Setanta | 240813T043015Z | bb94 |
| 019 | Haskell + hgl | 240715T005925Z | Wheat Wi |
| 020 | APL+WIN | 240708T145932Z | Graham |
| 007 | Vyxal | 240707T225405Z | emanresu |
| 046 | Haskell | 240708T224853Z | DPD- |
| 022 | Wolfram Language Mathematica | 240708T163409Z | att |
| 007 | MATL | 240707T222154Z | Luis Men |
| 058 | Ruby | 240708T105955Z | G B |
| 060 | JavaScript ES6 | 240707T213846Z | Arnauld |
| 010 | 05AB1E | 240708T075629Z | Kevin Cr |
| 105 | Python 3 | 240708T074215Z | Jitse |
| 036 | R | 240708T054306Z | pajonk |
| 004 | Nekomata + e | 240708T035232Z | alephalp |
| 011 | PARI/GP | 240708T023321Z | alephalp |
| 012 | Charcoal | 240707T221329Z | Neil |
APL(NARS), 15 chars
{(*/⍴⍵)=×⍨-.×⍵}
One Hadamard matrix is a M matrix, each elment are +-1 (already proven by input restriction)
is quadratic (already proven by input restrictions) that det(M)^2=n^n where nxn is the dimension of the matrix.
{(*/⍴⍵)=×⍨-.×⍵}
| ^^ ^------- "-.×" make determinant of input ⍵
| ||--------- "×⍨" make mult of input on right by itself will be det(⍵)^2 there
| |------------"=" is equal to
|----------------"*/⍴⍵" "⍴⍵" get dimensions of input ⍵ and "*/" elevate the first by the second
It should return 1 if the input is a Hadamard matrix, else should return 0; test:
{((,1)≡∪∣,⍵)∧(*/⍴⍵)=×⍨-.×⍵}2 2⍴ 1 1 1 ¯1
1
{(*/⍴⍵)=×⍨-.×⍵} 4 4⍴ 1 1 1 1 1 ¯1 1 ¯1 1 1 ¯1 ¯1 1 ¯1 ¯1 1
1
{(*/⍴⍵)=×⍨-.×⍵} 2 2⍴ 1 1 1 ¯1
1
{(*/⍴⍵)=×⍨-.×⍵} 4 4⍴ 1 ¯1 1 ¯1 ¯1 1 ¯1 1 1 ¯1 1 ¯1 ¯1 1 ¯1 1
0
{(*/⍴⍵)=×⍨-.×⍵} 1 1⍴1
1
Google Sheets, 51 bytes
lambda(a,b,sum(byrow(b,lambda(r,sumproduct(a,r)))))
This is a Google Sheets lambda function that expects two parameters: a should point to a 2D array that contains the first row in the matrix, and b should point to a 2D array that holds the rest of the rows in the matrix.
The function assumes that the matrix in the format specified in the question, and returns 0 if it is a Hadamard matrix and a non-zero value otherwise. In the event of a 1x1 matrix like [[1]], a should point to the matrix and b should point to a null array of zero rows, and the formula will return 0.

You can call the function like this:
=lambda(a, b,
sum(byrow(b, lambda(r, sumproduct(a, r))))
)(A1:D1, A2:D4)
...where a is A1:D1 and bis A2:D4.
Jelly, 7 bytes
Œcḋ/€S¬
Finds all combinations of 2 rows (Œc), calculates the dot product for each (ḋ/€) and sums (S). If this sum is greater than 0, then there exists a pair of rows that is non-orthogonal. Finally, take the logical inverse (¬).
Alternative (8 bytes)
ÆḊ²=L*`$
Tests whether the square determinant (ÆḊ²) is equal to the length of the input, to the power of itself (L*`$). This works as \$\det(H)=\pm n^{n/2} \iff n\$ is a Hadamard matrix.
Setanta, 102 bytes
gniomh(m){b:=0le i idir(0,fad@m)le j idir(0,i){s:=0le k idir(0,fad@m)s+=m[i][k]*m[j][k]b=b|s}toradh!b}
Haskell + hgl, 19 bytes
mF(q0<sm)<xQ(zW ml)
Explanation
This takes all pairs of rows \$(a,b)\$ where \$a\$ comes before \$b\$, computes the dot product and checks that the result is always zero.
xQcomputes the pairszW mlmultiplies the rows pairwisesmperforms the sum to get the dot productq0compares it to zeromFfolds using logical and.
Reflection
I'm pretty pleased with this overall. The library is not really built with a lot of linear algebra functions (yet). So this is not a task I should expect this to do very well at. It's not stellar, but it is passable considering everythign. I'm very happy that xQ exists.
- There could be a dot product builtin. This would make this much shorter.
xQshould be refactored to take a foldable so this could operate on actual vector types instead of lists.
APL+WIN, 19 20 bytes
+1 to fix problem identified by att
Prompts for matrix. 1 = true, 0 = false
(×/⍴m)=+/+/|m+.×⍉m←⎕
Vyxal, 7 bytes
ÞḊ²$@Π=
Try it Online! -1 thanks to att.
ÞḊ # Is determinant
² # squared
= # equal to
$@ # Length of input
Π # To the power of itself?
Haskell, 47, 46 bytes
- -1 byte thanks to xnor
f(x:y)=[]==y||all((0==).sum.zipWith(*)x)y&&f y
sum.zipWith(*)computes the scalar product of two vectorsxis the first row,yall the next rows- we check that for all other rows in
ythe scalar product with the current rowxis zero - then we repeat the check discarding the first row (Haskell works well with recursion)
MATL, 9 7 bytes
Thanks to @alephalpha for a correction (the transpose was originally missing).
t!Y*XR~
Inputs a matrix. Outputs a a matrix of ones (which is truthy) if the input is a Hadamard matrix, or a matrix containing at least a zero (which is falsy) otherwise.
Try it online! Or verify all test cases.
How it works
t % Implicit input: matrix M, of size n, with 1 or −1 entries. Duplicate
! % Transpose
Y* % Matrix product. This is a scalar matrix if and only if M is Hadamard
XR % Set entries on the diagonal and below to 0
~ % Negate each entry. Implicit display
JavaScript (ES6), 60 bytes
Returns false for Hadamard or true for non-Hadamard.
m=>m.some(p=>m.some(q=>p!=q&&p.reduce((t,v,x)=>t+v*q[x],0)))
Commented
m => // m[] = input matrix
m.some(p => // for each row p[] in m[]:
m.some(q => // for each row q[] in m[]:
p != q && // test whether p[] is not equal to q[]
// (comparison of pointers)
p.reduce( // for each value v at position x in p[],
(t, v, x) => // using t as the accumulator:
t + v * q[x], // add v * q[x] to the accumulator,
// which gives 1 if v = q[x] or -1 otherwise
0 // start with t = 0
) // end of reduce() -> gives 0 if and only if
// exactly half of the values are matching
) // end of inner some()
) // end of outer some()
05AB1E, 11 10 bytes
δ*OZ/āDδQQ
Port of @alephalpha's PARI/GP answer, so make sure to upvote that answer as well!
Try it online or verify all test cases.
Explanation:
δ*O # Matrix multiplicate the (implicit) input with itself:
δ # Apply double-vectorized, using two times the (implicit) input-matrix:
* # Vectorized multiply
O # Sum each inner row together
Z # Push the flattened maximum (without popping the matrix)
/ # Divide each inner value by this maximum
āDδQ # Push an identity-matrix of the same size:
ā # Push a list in the range [1,length] (without popping)
D # Duplicate it
δ # Apply double-vectorized again:
Q # Check whether the values are equal
Q # Check if the earlier matrix equals the identity-matrix
# (after which the result is output implicitly)
Python 3, 105 bytes
f=lambda a,x=2:x<1or all(sum(map(int.__eq__,i,j))*2==len(i)for i in a for j in{*a}-{i})*f([*zip(*a)],x-1)
R, 36 bytes
\(H)any(H%*%t(H)-diag(n<-nrow(H))*n)
Uses the characterization: \$HH^T=nI_n\$.
Outputs swapped TRUE/FALSE.
Nekomata + -e, 4 bytes
Sđ∙Z
This swaps truthy and falsy values. It outputs False if the input is a Hadamard matrix, and True otherwise.
Sđ∙Z
S Find a subset of the input
đ whose length is 2
∙ and the dot product of the two elements
Z is nonzero
-e checks if there is a solution.
Nekomata + -e, 6 bytes
ᵒ∙jZ‼*
ᵒ∙jZ‼*
ᵒ∙ Outer product with dot product
This is equivalent to multiplying the matrix by its transpose
j Join the matrix into a single list
Z‼ Remove zeros
* Check if it has the same length as the input
Nekomata does not allow multiplying two lists of different lengths
PARI/GP, 11 bytes
a->a*a~==#a
Let \$A\$ be the input matrix. Since it is guaranteed to contain only 1 and -1, we only need to check if \$A A^T = n I\$, where \$n\$ is the number of rows in \$A\$. When comparing a matrix with a scalar, PARI/GP will automatically multiply the scalar by the identity matrix of the same size.
Charcoal, 12 bytes
⊙θ⊙θ∧⁻κμΣ×ιλ
Attempt This Online! Link is to verbose version of code. Outputs an inverted Charcoal boolean, i.e. - if not Hadamard, nothing if Hadamard, Explanation:
⊙ Input array
θ Any row satisfies
⊙ Input array
θ Any row satisfies
κ Outer index
⁻ Does not equal
μ Inner index
∧ Logical And
ι Outer row
× Vectorised product with
λ Inner row
Σ Has nonzero sum
Implicitly print