找出所有具有重复值的(对角)对角线


17

挑战:

给定矩阵输入,确定具有重复数字的对角线和反对角线的数量。
因此,如果我们有一个像这样的矩阵:

[[aa,ab,ac,ad,ae,af],
 [ba,bb,bc,bd,be,bf],
 [ca,cb,cc,cd,ce,cf],
 [da,db,dc,dd,de,df]]

所有对角线和反对角线将是:

[[aa],[ab,ba],[ac,bb,ca],[ad,bc,cb,da],[ae,bd,cc,db],[af,be,cd,dc],[bf,ce,dd],[cf,de],[df],
 [af],[ae,bf],[ad,be,cf],[ac,bd,ce,df],[ab,bc,cd,de],[aa,bb,cc,dd],[ba,cb,dc],[ca,db],[da]]

例:

[[1,2,1,2,1,2],
 [1,2,3,4,5,6],
 [6,5,4,3,2,1],
 [2,1,2,1,2,1]]

所有对角线和反对角线将是:

[[1],[2,1],[1,2,6],[2,3,5,2],[1,4,4,1],[2,5,3,2],[6,2,1],[1,2],[1],
 [2],[1,6],[2,5,1],[1,4,2,1],[2,3,3,2],[1,2,4,1],[1,5,2],[6,1],[2]]

删除仅包含唯一数字的所有对角线和反对角线:

[[2,3,5,2],[1,4,4,1],[2,5,3,2],[1,4,2,1],[2,3,3,2],[1,2,4,1]]

因此,输出为包含重复数字的对角线和反对角线的数量:

6

挑战规则:

  • 如果输入矩阵为空,仅包含1个数字或整个矩阵中仅包含唯一数字,则输出始终为0
  • 确保输入仅包含正数[1,9](除非它完全为空)。
  • 矩阵将始终为矩形(即,所有行的长度均相同)。
  • I / O是灵活的。输入可以作为整数列表的列表,或者作为整数的2D数组,或者作为矩阵对象,作为字符串等。也可以将矩阵的一个或两个维度作为附加输入。是否以您选择的语言保存字节。

通用规则:

  • 这是,因此最短答案以字节为单位。
    不要让代码高尔夫球语言阻止您发布使用非代码高尔夫球语言的答案。尝试针对“任何”编程语言提出尽可能短的答案。
  • 标准规则适用于具有默认I / O规则的答案,因此允许您使用STDIN / STDOUT,具有适当参数的函数/方法以及返回类型的完整程序。你的来电。
  • 默认漏洞是禁止的。
  • 如果可能的话,请添加一个带有测试代码的链接(即TIO)。
  • 另外,强烈建议为您的答案添加说明。

测试用例:

Input:                     Output:

[[1,2,1,2,1,2],            6
 [1,2,3,4,5,6],
 [6,5,4,3,2,1],
 [2,1,2,1,2,1]]

[[]]                       0

[[1,2],                    0
 [3,4]]

[[1,1],                    2
 [1,1]]

[[9,9,9],                  6
 [9,9,9],
 [9,9,9]]

[[7,7,7,7],                8
 [7,7,7,7],
 [7,7,7,7]]

[[1,1,1],                  1
 [2,3,4],
 [2,5,1]]

[[1,8,4,2,9,4,4,4],        12
 [5,1,2,7,7,4,2,3],
 [1,4,5,2,4,2,3,8],
 [8,5,4,2,3,4,1,5]]

[[1,2,3,4],                4
 [5,6,6,7],
 [8,6,6,9],
 [8,7,6,5]]

Answers:


4

果冻,10 字节

ŒD;ŒdQƑÐḟL

在线尝试!签出测试套件!

备择方案:

ŒD;ŒdQƑ€¬S
ŒD;ŒdQƑ€ċ0

怎么运行的?

ŒD;ŒdQƑÐḟL – Monadic link / Full program.
  ;        – Join:
ŒD           – The diagonals
             with
   Œd        – The anti-diagonals.
       Ðḟ  – Discard the lists that are not:
     QƑ      – Invariant under deduplication.
         L – Length (count them).

10

R92 86 82 78字节

function(m,x=row(m),y=col(m),`|`=split,`^`=Map)sum(max^table^c(m|x-y,m|x+y)>1)

在线尝试!

说明

Xÿ

X-ÿ

0 -1 -2 -3 1 0 -1 -2 2 1 0 -1 3 2 1 0

X+ÿ

2 3 4 5 3 4 5 6 4 5 6 7 5 6 7 8

现在split(m, x-y)split(m, x+y)生成对角线和反对角线的实际列表,我们将它们合并在一起。

最后,我们对结果列表中存在重复项的条目进行计数。

感谢您保存的字节数:

通过-4 CriminallyVulgar
-4通过digEmAll


1
我想我可以添加rowcol我的'非常情境的功能列表中。真正聪明的解决方案。
CriminallyVulgar

1
我认为您可以c(m|x-y,m|x+y)直接将其移到sapply调用中,然后删除该l=部分。我看不到任何失败的测试。在线尝试!
CriminallyVulgar

是的,没错,我只是错过了第一次高尔夫比赛后只剩下一个l实例的机会。
Kirill L.

1
他们今天早上一定在R中添加了rowcolumn函数,因为我从未听说过它们。
ngm

5

J21 20字节

-1字节感谢乔纳!

1#.|.,&((~:&#~.)/.)]

在线尝试!

说明:

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 

1
它是一种疯狂的,你不能做的不比(-.@-:~.)在J“的独特的项目不匹配”,但我已经遇到过很多次也是一样,我不认为你可以......我们已经=~:上一个手和-:<this is missing>
乔纳

实际上,设法减少了1个字节:1#.|.,&((~:&#~.)/.)]在线尝试!
乔纳

@乔纳:很酷的使用&,谢谢!
加伦·伊万诺夫

5

Japt,31个字节

ËcUî
ËéEÃÕc¡XéYnÃÕ mf fÊk_eZâÃl

尝试所有测试用例

说明:

Ë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

我还尝试基于Kirill L.的Haskell答案的版本,但找不到“按X和Y索引的函数分组”的好方法,而我发现的替代方法还不够好。



4

的JavaScript(ES6), 107个105 101  98字节

f=(m,d=s=1)=>(m+0)[s-=~d/2]?m.some(o=(r,y)=>!r.every((v,x)=>x+d*y+m.length-s?1:o[v]^=1))+f(m,-d):0

在线尝试!

注意

编写此代码的方式从未测试过由底部左下角单元组成的反对角线。可以,因为它不可能包含重复的值。

已评论

f = (                    // f = recursive function taking:
  m,                     //   m[] = input matrix
  d =                    //   d   = direction (1 for anti-diagonal or -1 for diagonal)
  s = 1                  //   s   = expected diagonal ID, which is defined as either the sum
) =>                     //         or the difference of x and y + the length of a row
  (m + 0)[               //
    s -= ~d / 2          // increment s if d = -1 or leave it unchanged otherwise
  ] ?                    // if s is less than twice the total number of cells:
    m.some(o =           //   o = object used to store encountered values in this diagonal
    (r, y) =>            //   for each row r[] at position y in m[]:
      !r.every((v, x) => //     for each cell of value v at position x in r[]:
        x + d * y +      //       x + d * y + m.length is the ID of the diagonal
        m.length - s ?   //       if it's not equal to the one we're looking for:
          1              //         yield 1
        :                //       else:
          o[v] ^= 1      //         toggle o[v]; if it's equal to 0, v is a duplicate and
                         //         every() fails which -- in turn -- makes some() succeed
      )                  //     end of every()
    )                    //   end of some()
    + f(m, -d)           //   add the result of a recursive call in the opposite direction
  :                      // else:
    0                    //   stop recursion

4

05AB1E,25个字节

í‚εεygÅ0«NFÁ]€ø`«ʒ0KDÙÊ}g

在线尝试! 或作为测试套件

说明

í                          # reverse each row in input
 ‚                         # and pair with the input
  ε                        # for each matrix
   ε                       # for each row in the matrix
    ygÅ0«                  # append len(row) zeroes
         NFÁ               # and rotate it index(row) elements to the right
            ]              # end loops
             €ø            # transpose each matrix
               `«          # append them together
                 ʒ     }   # filter, keep only rows that
                  0K       # when zeroes are removed
                    DÙÊ    # are not equal to themselves without duplicate values                           
                        g  # push length of the result

我觉得我在这里错过了什么。
需要稍后再尝试打高尔夫球。


1
完全没有帮助,但是现在rotate N left就可以N._了。因此í‚εεygÅ0«N._]也可以。也可以通过此新更改删除拼合...尽管仍不节省字节:í‚vyεygÅ0«N._}ø}«ʒ0KDÙÊ}g
Magic Octopus Urn

1
@MagicOctopusUrn:有趣。我错过了那个命令。虽然只有一个。那真是怪了。
Emigna

1
@Emigna N(._我猜你可以正确地做,但是你NFÁ}的长度是一样的,在这种情况下甚至更短,因为同时]关闭了循环和映射。总体而言._,与相比,仅在左移保存1个字节时才有用NFÀ}
凯文·克鲁伊森

@KevinCruijssen:啊,很酷。虽然如您所说,不是很有用。
Emigna '19

3

Python 2中144个 136字节

lambda m:sum(l(set(d))<l(d)for d in[[r[i*x+o]for i,r in enumerate(m)if-1<i*x+o<l(r)]for o in range(-l(`m`),l(`m`))for x in[-1,1]])
l=len

在线尝试!


3

八度,98字节

@(A)nnz([(q=@(Q)arrayfun(@(n)nnz(z=diag(Q,n))-nnz(unique(z)),-([m,n]=size(Q)):n))(A),q(rot90(A))])

在线尝试!


1
数组真的很有趣吗?; p
Kevin Cruijssen

感谢您准备八度格式的测试用例!
路易斯·门多

2
@KevinCruijssen不只是数组!您也可以拥有cellfun,对于受虐狂structfun也是如此。在Octave中,它可以是for循环或具有fun
Sanchises

并且不要忘记b-sx-fun!
Luis Mendo

3

Haskell,118112字节

import Data.List
r#(a:b)=sum[1|(/=)=<<nub$[h|h:_<-a:r]]+[t|_:t<-a:r]#b
[]#_=0
a#_=a#[[]]
h x=[]#x+[]#(reverse x)

在线尝试!

r#(a:b)                      -- function '#' calculates the ant-diagonals of a matrix
                             -- where 'a' is the first row and 'b' all the others
                             -- as we recursively walk down the rows of the matrix,
                             -- 'r' holds the rows from before with the respective
                             -- head dropped
                             --
          [h|h:_<-a:r]       -- if the heads of the the current row and the rows
                             -- before
       (/=)=<<nub$           -- contain duplicates
    [1|                ]     -- make a singleton list [1] (else the empty list)
 sum                         -- and take the sum thereof
      +                      -- and add
             #               -- a recursive call with
 [t|_:t<-a:r]                -- the tails of the current row and the rows before
              b              -- and the rows below
                             --
[]#_=0                       -- base case if there aren't any tails anymore, return 0
a#_=a#[[]]                   -- if there are tails, but no further rows below,
                             -- continue with tails

h x=[]#x+[]#(reverse x)      -- main function, call '#' with input matrix 'x'
                             -- and the reverse of it to get the number of diagonals
                             -- and anti-diagonals. Recursion starts with no
                             -- rows before the 1st row.

-- example trace of function '#'
-- input matrix:
--   [[1,2,3,4],
--    [5,6,7,8],
--    [9,9,9,9]]
--
--  | r         a          b              a:r          heads   tails (r of next call)
-- -+----------------------------------------------------------------------------------
-- 1| []        [1,2,3,4]  [[5,6,7,8],    [[1,2,3,4]]  [1]     [[2,3,4]]
--  |                       [9,9,9,9]]
--  | 
-- 2| [[2,3,4]]  [5,6,7,8]  [[9,9,9,9]]   [[5,6,7,8],  [5,2]   [[6,7,8],
--  |                                      [2,3,4  ]]           [3,4  ]]
--  |
-- 3| [[6,7,8],  [9,9,9,9]  []            [[9,9,9,9],  [9,6,3] [[9,9,9],
--  |  [3,4  ]]                            [6,7,8  ],           [7,8  ]
--  |                                      [3,4    ],           [4    ]
--  |
--  | ....

2

木炭61 56 53字节

F²FLθFL§θ⁰F⟦⁻κ×⊖⊗ιλ⟧⊞υ⊞O⎇∧λ﹪⁺μιLθ⊟υ⟦⟧§§θμλILΦυ⊙ι‹⌕ιλμ

在线尝试!链接是详细版本的代码。说明:

F²

循环向前和向后对角线;i=0代表正对角线,而i=1代表反向对角线。

FLθ

循环遍历每行索引。这代表对角线起点的索引。

FL§θ⁰«

循环遍历每个列索引。

F⟦⁻κ×⊖⊗ιλ⟧

在此列索引处计算对角线的行索引。我for在单元素数组上使用循环而不是赋值,因为这样可以避免使用以下语句将赋值包装到一个块中,从而节省了一个字节。

⎇∧λ﹪⁺μιLθ

检查这是第一列还是对角线将在底部和顶部之间环绕。

⊟υ

如果不是,则从列表列表中弹出最后一个列表。

⟦⟧

如果是,则启动一个新的空列表。

⊞O...§§θμλ

将当前对角线条目添加到该列表。

⊞υ

并将该列表(返回)推到列表列表中。

ILΦυ⊙ι‹⌕ιλμ

计算包含重复项的列表数。

让我们举一个例子,何时i=0k=1。这意味着我们已经收集了两个对角线[[1,1,5,2],[9,4,3,5]]。这是我们的输入:

 1 8 4 2 9 4 4 4
[5]1 2 7 7 4 2 3
 1 4 5 2 4 2 3 8
 8 5 4 2 3 4 1 5

然后l,我们从循环07。每次行和列都前进1:

 1 8 4 2 9 4 4 4
[5]1 2 7 7 4 2 3
 1[4]5 2 4 2 3 8
 8 5[4]2 3 4 1 5

现在的清单是[[1,1,5,2],[9,4,3,5],[5,4,4]]。但是,当l为时3,我们具有k+l=4数组高度的倍数。这意味着我们需要开始一个新列表:[[1,1,5,2],[9,4,3,5],[5,4,4],[]]。然后,我们继续收集对角元素:

 1 8 4[2]9 4 4 4
[5]1 2 7[7]4 2 3
 1[4]5 2 4[2]3 8
 8 5[4]2 3 4[1]5

现在的清单是[[1,1,5,2],[9,4,3,5],[5,4,4],[2,7,2,1]]。现在,当l是时7,我们有k+l=8,是数组高度的另一个倍数。这意味着我们需要开始一个新列表,该列表以该对角线的最后一个元素结尾[[1,1,5,2],[9,4,3,5],[5,4,4],[2,7,2,1],[4]]

 1 8 4[2]9 4 4[4]
[5]1 2 7[7]4 2 3
 1[4]5 2 4[2]3 8
 8 5[4]2 3 4[1]5

通过收集从每一行的第一个元素开始的包装对角线,我们最终累积了数组的所有对角线。


2

Wolfram语言(Mathematica)99 98 96 94 83字节

Count[DuplicateFreeQ@Diagonal[#,i]~Table~{i,-t,t=#~Total~2}&/@{#,Reverse@#},1<0,2]&

在线尝试!

  • Function[a,a~Diagonal~#&/@Range[t=-#~Total~2,-t]]取得a-的所有对角线,这是有效的,因为#~Total~2它大于的任何维度a

1

APL + WIN,69个字节

提示形式为46⍴12 1 2 1 2 1 2 1 2 3 2 5 4 6 6 5 4 3 2 1 2 1 2 1 2 1 2d的2d矩阵

这样产生:

1 2 1 2 1 2
1 2 3 4 5 6
6 5 4 3 2 1
2 1 2 1 2 1

+/~(v⍳¨v)≡¨⍳¨⍴¨v←(v←⊂[1](⌽0,⍳1↓n)⌽(n⍴0),m,((n←0 ¯1+↑⍴m)⍴0),⌽m←⎕)~¨0

在线尝试!由Dyalog Classic提供

说明:

(⌽0,⍳1↓n)⌽(n⍴0),m pad m with zeros to isolate diagonals

((n←0 ¯1+↑⍴m)⍴0),⌽m pad rotated m with zeros to isolate anti-diagonals

产量:

1 2 1 2 1 2 0 0 0 2 1 2 1 2 1 0 0 0
0 1 2 3 4 5 6 0 0 0 6 5 4 3 2 1 0 0
0 0 6 5 4 3 2 1 0 0 0 1 2 3 4 5 6 0
0 0 0 2 1 2 1 2 1 0 0 0 1 2 1 2 1 2

v←(v←⊂[1](.....)~¨0 enclose the diagonals as a nested vector with padded zeros removed

+/~(v⍳¨v)≡¨⍳¨⍴¨v identify diagnols with duplicate entries and sum


1

TSQL,140个 128字节

找到一种打高尔夫球的方法,可以打12个字符。这不再是最长的解决方案。

打高尔夫球:

SELECT sum(iif(y+x=j+i,1,0)+iif(y-x=j-i,1,0))FROM
@,(SELECT x i,y j,max(y)over()m,v w
FROM @)d WHERE(x*y=0or m=y)and v=w and x<i

取消高尔夫:

DECLARE @ table(v int,x int,y int)
-- v = value
-- x = row 
-- y = column
INSERT @ values
(1,0,0),(2,0,1),(1,0,2),(2,0,3),(1,0,4),(2,0,5),
(1,1,0),(2,1,1),(3,1,2),(4,1,3),(5,1,4),(6,1,5),
(6,2,0),(5,2,1),(4,2,2),(3,2,3),(2,2,4),(1,2,5),
(2,3,0),(1,3,1),(2,3,2),(1,3,3),(2,3,4),(1,3,5)


SELECT sum(iif(y+x=j+i,1,0)+iif(y-x=j-i,1,0))
FROM @,(SELECT x i,y j,max(y)over()m,v w FROM @)d
WHERE
  (x*y=0or m=y)
  and v=w
  and x<i

试试看

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.