A matrix is antisymmetric, or skew-symmetric, if its transpose equals its negative.
The transpose of a matrix can be obtained by reflecting its elements across the main diagonal. Examples of transpositions can be seen here:
\$\begin{pmatrix}11&12&13\21円&22&23\end{pmatrix}\rightarrow\begin{pmatrix}11&21\12円&22\13円&23\end{pmatrix}\$
\$\begin{pmatrix}11&12&13\21円&22&23\31円&32&33\end{pmatrix}\rightarrow\begin{pmatrix}11&21&31\12円&22&32\13円&23&33\end{pmatrix}\$
This matrix is antisymmetric because it equals its transpose when multiplied by -1:
\$\begin{pmatrix}0&2&-1\\-2&0&0\1円&0&0\end{pmatrix}\$
All antisymmetric matrices exhibit certain characteristics:
Antisymmetry can only be found on square matrices, because otherwise the matrix and its transpose would be of different dimensions.
Elements which lie on the main diagonal must equal zero because they do not move and consequently must be their own negatives, and zero is the only number which satisfies \$x=-x\$.
The sum of two antisymmetric matrices is also antisymmetric.
The Challenge
Given a square, non-empty matrix which contains only integers, check whether it is antisymmetric or not.
Rules
This is code-golf so the shortest program in bytes wins.
Input and output can assume whatever forms are most convenient as long as they are self-consistent (including output which is not truthy or falsy, or is truthy for non-antisymmetry and falsy for antisymmetry, etc).
Assume only valid input will be given.
Test Cases
In:
1 1 1
1 1 1
1 1 1
Out: False
In:
0 0 1
0 0 0
-1 0 0
Out: True
In:
0 -2
2 0
Out: True
-
2\$\begingroup\$ Speaking of skew-symmetry... That's totally different though since that one is in the CA sense. \$\endgroup\$TwilightSparkle– TwilightSparkle2020年08月03日 00:40:09 +00:00Commented Aug 3, 2020 at 0:40
-
3\$\begingroup\$ What type of outputs can be used? Any two consistent values? Any truthy and falsy values? Can we choose falsy for antisymmetric and truthy for symmetric? \$\endgroup\$Luis Mendo– Luis Mendo2020年08月03日 09:30:12 +00:00Commented Aug 3, 2020 at 9:30
-
7\$\begingroup\$ Will the input ever contain complex numbers? Only contain real numbers? Only integers? \$\endgroup\$Luis Mendo– Luis Mendo2020年08月03日 10:20:59 +00:00Commented Aug 3, 2020 at 10:20
-
1\$\begingroup\$ @LuisMendo I do believe your first comment is addressed by rule 2, but examples were added anyway. Additionally, only integers will be present (also added). For the record I do want to delete this question but I can't. \$\endgroup\$golf69– golf692020年08月03日 20:17:20 +00:00Commented Aug 3, 2020 at 20:17
-
1\$\begingroup\$ @user That's Do X Without Y, obviously, and is thus deprecated. \$\endgroup\$TwilightSparkle– TwilightSparkle2020年08月04日 03:55:40 +00:00Commented Aug 4, 2020 at 3:55
33 Answers 33
APL (Dyalog Unicode), 3 bytes
-≡⍉
This is exactly an APLcart entry on "antisymmetric". Basically it checks if the input's negative - matches ≡ the input's transpose ⍉.
Brachylog, 5 bytes
5 bytes seems to be the right length for this (unless you're Jelly). Actually, this would be three bytes if Brachylog implicitly vectorized predicates like negation.
\ṅm2?
Explanation
\ Transpose
ṅm2 Map negation at depth 2
? Assert that the result is the same as the input
-
\$\begingroup\$ How do you program in this language without using something like windows character map or a special keyboard with 5000 keys? \$\endgroup\$Daniel W.– Daniel W.2020年08月04日 19:09:53 +00:00Commented Aug 4, 2020 at 19:09
-
1\$\begingroup\$ @DanielW. Good question! I have two methods: copying and pasting from the codepage chart, and using a bookmarklet of Adám's language bar (also available for several other languages). \$\endgroup\$DLosc– DLosc2020年08月05日 03:01:49 +00:00Commented Aug 5, 2020 at 3:01
C (gcc), (削除) 67 (削除ここまで) 64 bytes
-3 thanks to AZTECCO
i,j;f(m,s)int**m;{for(i=j=0;i=i?:s--;)j|=m[s][--i]+m[i][s];m=j;}
Returns 0 if the matrix is antisymmetric, and a nonzero value otherewise.
Octave, 19 bytes
@(a)isequal(a',-a);
The semicolon doesn't need to be there, but it outputs the function otherwise, so I'll take the one-byte hit to my score for now.
Explanation
It's pretty straightforward - it checks to see if the matrix of the transpose is equal to the negative matrix
JavaScript (ES6), 42 bytes
Returns false for antisymmetric or true for non-antisymmetric.
m=>m.some((r,y)=>r.some((v,x)=>m[x][y]+v))
Io, 67 bytes
method(~,~map(i,,円\map(I,V,V+x at(I)at(i)))flatten unique==list(0))
Explanation
For all a[x][y], it checks whether all a[x][y]+a[y][x]==0.
method(~, // Input x.
~ map(i,,円 // Map all x's rows (index i):
\ map(I,V, // Foreach the rows (index I):
V+x at(I)at(i) // x[i][I] + x[I][i]
)
) flatten // Flatten the resulting list
unique // Uniquify the list
==list(0) // Does this resulting list *only* contain the item 0?
)
-
\$\begingroup\$ Hi "new contributor" +1~~~ \$\endgroup\$TwilightSparkle– TwilightSparkle2020年08月03日 01:29:07 +00:00Commented Aug 3, 2020 at 1:29
Pyth, 5 bytes
qC_MM
Explanation
qC_MM
q : Check if input equals
C : Transpose of
_MM : Negated input
MATL, 5 bytes
!_GX=
Explanation
!_GX=
// Implicit input on top of stack
! // Replace top stack element with its transpose
_ // Replace top stack element with its negative
G // Push input onto stack
X= // Check for equality
Charcoal, 10 bytes
=θEθEθ±§λκ
Try it online! Link is to verbose version of code. Outputs a Charcoal boolean, i.e. - if the matrix is antisymmetric, nothing if not. Explanation:
Eθ Map over input matrix rows (should be columns, but it's square)
Eθ Map over input matrix rows
§λκ Cell of transpose
± Negated
=θ Does matrix equal its negated transpose?
Wolfram Mathematica, (削除) 20 (削除ここまで), 7 bytes
There is a built-in function for this task:
AntisymmetricMatrixQ
But one can simply write a script with less byte counts:
#==-#T&
The T character, as it is displayed in notebooks, stands for transpose. But if you copy this into tio, it won't be recognized because these characters are only supported by Mathematica notebooks.
-
1\$\begingroup\$ I don't think the transpose sign (Unicode: F3C7) should count as one byte? \$\endgroup\$M. Stern– M. Stern2020年08月03日 18:14:00 +00:00Commented Aug 3, 2020 at 18:14
-
\$\begingroup\$ @M.Stern Maybe I am wrong, but I look at it the same way as
⍉in the highest voted answer counts as one byte. \$\endgroup\$polfosol ఠ_ఠ– polfosol ఠ_ఠ2020年08月03日 18:15:57 +00:00Commented Aug 3, 2020 at 18:15 -
6\$\begingroup\$ @polfosolఠ_ఠ APL has a custom code page. The character for
Transposeis, which is 3 bytes. Try it online! \$\endgroup\$att– att2020年08月03日 18:59:00 +00:00Commented Aug 3, 2020 at 18:59
Google Sheets, (削除) 90 (削除ここまで) (削除) 88 (削除ここまで) 41
(Now with lambdas)
Closing parens discounted.
Named Functions (name, args, and formula text all count):
| Name | args | Formula |
|---|---|---|
P |
a, b |
a+b |
Q |
a |
MAP(a,TRANSPOSE(a),P) |
Formula:
=SUM(Q(A1:C3))
No, I cannot currently use ADD instead of P as it is not a lambda.
How it Works:
Add the matrix to its transpose. If the resulting matrix is all 0's, then the sum of all elements is 0, which means we the two are equal.
Return 0 if equal, some positive number otherwise.
Haskell, 40 bytes
(==)<*>foldr(zipWith(:).map(0-))z
z=[]:z
Uses this tip for shorter transpose and the idiom of (==)<*> to check invariance under an operation.
Haskell, (削除) 49 (削除ここまで) 47 bytes
import Data.List
f x=x==transpose(map(0-)<$>x)
- saved 2 thanks to @Unrelated String
My first Haskell.
Function tacking a matrix and checking if input is equal to input mapped to (0-value) and transposed
-
\$\begingroup\$ -2 with
<$>\$\endgroup\$Unrelated String– Unrelated String2022年09月26日 21:04:06 +00:00Commented Sep 26, 2022 at 21:04
Scala, 32 bytes
l=>l.transpose==l.map(_.map(-_))
Finally, something that Scala has a builtin for!
The function's pretty straightforward - it compares the transpose of a List[List[Int]](doesn't have to be a List, could be any Iterable) to the negative, found by mapping each list inside l and using - to make it negative.
-
1\$\begingroup\$ I learned a bit of Ruby golfing and fixed it. \$\endgroup\$Razetime– Razetime2020年08月04日 13:43:07 +00:00Commented Aug 4, 2020 at 13:43
-
1\$\begingroup\$ Probably this is what you're referring to, but Tips for golfing in Ruby is a good resource if you haven't seen it. \$\endgroup\$Dingus– Dingus2020年08月05日 00:41:21 +00:00Commented Aug 5, 2020 at 0:41
-
\$\begingroup\$ Not saying much but using
_1for either of the map blocks saves two bytes. \$\endgroup\$south– south2023年06月22日 06:41:14 +00:00Commented Jun 22, 2023 at 6:41 -
\$\begingroup\$ it's on tio which used 2.7 or something. guess i'll just add the version number \$\endgroup\$Razetime– Razetime2023年06月26日 06:07:51 +00:00Commented Jun 26, 2023 at 6:07
Pip, 5 bytes
Z_=-_
A function submission; pass a nested list as its argument. Try it online!
Explanation
Z_ The argument, zipped together
= Equals
-_ The argument, negated
gorbitsa-ROM, 8 bytes
r1 R A1 B0 T
This is an awful abuse of rule
Input and output can assume whatever forms are most convenient.
If input takes form of "arr[i][j] arr[j][i]", the problem becomes "is sum = 0?".
This code takes pairs of values and outputs their sum if it's not 0
Thus if you provide matrix as previously mentioned pairs, code will return some value for not-anti-symmetric ones and will not return anything for anti-symmetric ones.
r1 R A1 B0 T
r1 #store first number
R #read second number
A1 #add first number
B0 #if sum==0, jump to the beginning
T #else output the sum
Java (JDK), (削除) 89 (削除ここまで) (削除) 87 (削除ここまで) 86 bytes
- -2 bytes thanks to Calculuswhiz!
m->{int i=0,j,r=1;for(;++i<m.length;)for(j=0;++j<i;)r=m[i][j]!=-m[j][i]?0:r;return r;}
Returns 0 for false and 1 for true.
-
1\$\begingroup\$ How about
int i=0,jthenj=0in the inner loop? \$\endgroup\$General Grievance– General Grievance2020年08月08日 01:01:03 +00:00Commented Aug 8, 2020 at 1:01 -
\$\begingroup\$ @Calculuswhiz Thanks! I almost never use commas for assignments and totally forgot about them \$\endgroup\$user– user2020年08月08日 15:30:48 +00:00Commented Aug 8, 2020 at 15:30
-
\$\begingroup\$ Oh, I found something better at 76:
m->{int l=m.length,i=l*l;while(--i>=0&&m[i%l][i/l]==-m[i/l][i%l]);return i;}. This returns-1only if antisymmetric, something bigger otherwise. Your original code might also have needed to start at -1's instead of 0's. \$\endgroup\$General Grievance– General Grievance2020年08月08日 17:19:04 +00:00Commented Aug 8, 2020 at 17:19 -
\$\begingroup\$ @Calculuswhiz That's really cool, you should post your own answer! \$\endgroup\$user– user2020年08月08日 17:32:06 +00:00Commented Aug 8, 2020 at 17:32
05AB1E, 3 bytes
ø(Q
Try it online or verify all test cases.
Explanation:
ø # Zip/transpose the (implicit) input-matrix; swapping rows/columns
( # Negate each value in this transposed matrix
Q # And check if it's equal to the (implicit) input-matrix
# (after which the result is output implicitly)
Raku, 26 bytes
{none flat $_ »+«[Z] $_}
$_is the input matrix, in the form of a list of lists of integers.[Z] $_is the transpose of the input matrix.»+«adds the input matrix to its transpose.flatflattens the matrix into a single list of numbers.noneconverts that list of numbers into a junction which is true if and only if none of the numbers is truthy, that is, nonzero.
The none-junction is returned. It is truthy only if adding the matrix to its transpose results in a matrix containing all zeroes.