Spot all (anti)diagonals with duplicated values
R, 92 86 82 78 bytes
function(m,x=row(m),y=col(m),`|`=split,`^`=Map)sum(max^table^c(m|x-y,m|x+y)>1)
Try it online!
Explanation
First, we declare additional variables \$x\$ and \$y\$ that stand for row and column indices, respectively. Then we can delineate the diagonals and anti-diagonals by taking their difference and sum. E.g., for a 4x4 matrix:
\$x-y\$ gives:
0 -1 -2 -3
1 0 -1 -2
2 1 0 -1
3 2 1 0
\$x+y\$ gives:
2 3 4 5
3 4 5 6
4 5 6 7
5 6 7 8
Now split(m, x-y)
and split(m, x+y)
produce the actual lists of diagonals and anti-diagonals, which we join together.
Finally, we count the entries of the resulting list where duplicates are present.
Thanks for bytes saved:
-4 by CriminallyVulgar
-4 by digEmAll
J, 21 20 bytes
-1 byte thanks to Jonah!
1#.|.,&((~:&#~.)/.)]
Try it online!
Explanation:
1#. find the sum of the
, concatenation of
( ) the result of the verb in the parentheses applied to
] the input
& and
|. the reversed input
( )/. for each diagonal
~:&#~. check if all elements are unique and negate the result
Japt, 31 bytes
ËcUî
ËéEÃÕc¡XéYnÃÕ mf fÊk_eZâÃl
Try all test cases
Explanation:
Ëc #Pad each row...
Uî #With a number of 0s equal to the number of rows
ËéEÃÕ #Get the anti-diagonals:
ËéEÃ # Rotate each row right a number of times equal to the row's index
Õ # Get the resulting columns
c #Add to that...
¡XéYnÃÕ #The diagonals:
¡XéYnà # Rotate each row left a number of times equal to the row's index
Õ # Get the resulting columns
mf #Remove the 0s from each diagonal
fÊ #Remove the all-0 diagonals
k_ Ã #Remove the ones where:
eZâ # The list contains no duplicates
l #Return the number of remaining diagonals
I also tried a version based on Kirill L.'s Haskell answer, but couldn't find a good way to "group by a function of the X and Y indices" and the alternative I found wasn't good enough.