检查矩阵是否为Toeplitz矩阵


11

将为您提供一个二维数组和一个数字,并要求您查找给定的矩阵是否为Toeplitz

输入格式:

您将获得一个将two-dimensional矩阵作为参数的函数。

输出格式:

返回1从功能,如果矩阵是托普利茨,否则返回-1

限制条件:

3 < n,m < 10,000,000

其中n,行m数是列数,而列数是列数。

样本测试案例:

Sample Input :
4 
5
6 7 8 9 2
4 6 7 8 9
1 4 6 7 8
0 1 4 6 7 

Sample Output : 
1 

计分

这是,因此最短的答案以字节为单位。


8
这是一个很好的挑战,但是我们在这里更喜欢宽松的I / O要求。我建议默认允许同时允许程序和功能。并且允许True / False或1/0作为输出,或者可能只是任意两个一致的不同输出,这似乎是决策问题的首选
xnor

15
同样,对Toeplitz的定义将是一个很好的定义,包括非Toeplitz在内的更多测试用例也会更好。不确定您对添加代码的含义。
xnor

5
我认为您必须减小n,m的最大值。否则,此挑战的主要部分是找到一种处理1 TB矩阵的方法。
Stewie Griffin's

1
矩阵元素将始终是非负整数吗?
马丁·恩德

Answers:


7

Mathematica,42个字节

2Boole[#==ToeplitzMatrix[#&@@@#,#&@@#]]-1&

Mathematica没有内置的功能来检查某物是否为Toeplitz矩阵,但它确实具有内置的功能来生成一个矩阵。因此,我们从输入的第一列(#&@@@#)和第一行(#&@@#)生成一个,然后检查它是否等于输入。要将True/ False结果转换为1/ -1我们使用Boole(给定10),然后简单地使用转换结果2x-1


6

八度,30字节

我假设我不必处理挑战中所说的1,000,000x1,000,000矩阵。这适用于不超过可用内存(在我的情况下小于1 TB)的矩阵。

@(x)x==toeplitz(x(:,1),x(1,:))

在线尝试!

这将矩阵x作为输入,并根据第一列和第一行上的值创建Toeplitz矩阵。然后它将检查矩阵的每个元素是否相等。如果所有元素均相等,则输入为Toeplitz矩阵。

输出将是与输入相同尺寸的矩阵。如果输出中有零,则认为是八度。

编辑:

刚注意到严格的输出格式:

这适用于41个字节。从该版本中可以打出一两个字节,但我希望输出规则会有所放宽。

@(x)2*(0||(x==toeplitz(x(:,1),x(1,:))))-1


5

05AB1E,11个字节

Œ2ùvy`¦s¨QP

在线尝试!

说明

Œ             # get all sublists of input
 2ù           # keep only those of length 2
   v          # for each such pair
    y`        # split to separate lists
      ¦       # remove the first element of the second list
       s¨     # remove the last element of the first list
         Q    # compare for equality
          P   # product of stack

4

Haskell,43个字节

f(a:b:t)|init a==tail b=f$b:t|1>0= -1
f _=1

在线尝试!


ang,再复杂不过了。奇怪的是,我将其减少为39个字节,输出为true / falsy,因此如果False允许Toeplitz = ,我可能会将其击败了一个字节。
与Orjan约翰森

3

Mathematica,94个字节

l=Length;If[l@Flatten[Union/@Table[#~Diagonal~k,{k,-l@#+1,l@#[[1]]-1}]]==l@#+l@#[[1]]-1,1,-1]&

输入

{{6,7,8,8,9,2},{4,6,7,8,9},{1,4,6,7,8},{0,1,4,6,7}}

另一个基于Stewie Griffin算法

Mathematica,44个字节

If[#==#[[;;,1]]~ToeplitzMatrix~#[[1]],1,-1]&

2
您需要定义s吗?您不能只使用它#吗?
不是一棵树

是!你是对的!
J42161217

3

Java 7中,239个 233 220 113字节

int c(int[][]a){for(int i=a.length,j;i-->1;)for(j=a[0].length;j-->1;)if(a[i][j]!=a[i-1][j-1])return -1;return 1;}

@Neil提示使用更有效算法后-107字节。

说明:

在这里尝试。

int c(int[][]a){                // Method with integer-matrix parameter and integer return-type
  for(int i=a.length,j;i-->1;)  //  Loop over the rows (excluding the first)
    for(j=a[0].length;j-->1;)   //   Loop over the columns (excluding the first)
      if(a[i][j]!=a[i-1][j-1])  //    If the current cell doesn't equal the one top-left of it:
        return -1;              //     Return -1
                                //   End of columns loop (implicit / single-line body)
                                //  End of rows loop (implicit / single-line body)
  return 1;                     //  Return 1
}                               // End of method

R&C在第一个功能中是什么?
米奇·杰克

@MickeyJack行和列(如果将其与挑战进行比较,则为r= nc= m)。
凯文·克鲁伊森

您不应该将数组作为参数传递给函数吗?此外,还有一种更有效的算法,可将您的字节数减少约50%。
尼尔

1
@KevinCruijssen只需检查所有不在第一行或第一列中的元素是否等于该元素在对角线上的左上角。
尼尔

1
啊,您甚至必须使用-->运算符!
尼尔

3

Haskell,51个字节

t 接受整数列表的列表并返回一个整数。

t m=1-sum[2|or$zipWith((.init).(/=).tail)=<<tail$m]

在线尝试!

可能为39或38个字节,输出为true / falsy。

使用该想法的init灵感来自Emigna的05AB1E答案,该答案使用了非常相似的方法。在此之前,我使用了嵌套拉链。

这个怎么运作

  • zipWith((.init).(/=).tail)=<<tail是的无分形式 \m->zipWith(\x y->tail x/=init y)(tail m)m
  • 这会m合并的每对连续的行,检查第一个元素被删除的第一个与第二个元素被删除的第二个是否不同。
  • or则结合了所有对行的检查。
  • 1-sum[2|...] 转换输出格式。

2

JavaScript(ES6),65 54字节

a=>a.some((b,i)=>i--&&b.some((c,j)=>c-a[i][j-1]))?-1:1

使用自己的技巧a=>a.some(b=>b.some((v,i)=>d[i]-(d[i]=v),d=[,...d]),d=[])?-1:1(62个字节)
Arnauld

1
@Arnauld谢谢,但事实证明,我再次考虑问题了……
尼尔(Neil)

2

红宝石,54个字节

->a,b,m{m.reduce{|x,y|x[0..-2]==y[1,b]?y:[]}.size<=>1}

完全符合规定,如果接受灵活的输入/输出,则可以打高尔夫球。

说明:

在矩阵上进行迭代,并将每行与上方的行进行比较,并向右移动一个。如果它们不同,则将空数组用于下一次迭代。最后,如果最终数组为空,则返回-1;如果至少2个元素,则返回1(由于最小的可能矩阵为3x3,如果所有比较均返回true,则为true)

在线尝试!


很好地使用<=>来计算结果!
尼尔

怎么样,|(*x,_),y|所以你不需要切片x
Stefan Pochmann

1

PHP,70个字节

<?=!preg_match('/\[([\d,]+?),\d+\],\[\d+,(?!\1)/',json_encode($_GET));

1

Python,108

r=range
f=lambda x,n,m:all([len(set([x[i][j] for i in r(n) for j in r(m) if j-i==k]))==1 for k in r(1-n,m)])

完全没有效率,因为它n+m在过滤对角线时触及每个元素时间。然后检查每个对角线是否有一个以上的唯一元素。


1

公理,121字节

f(m)==(r:=nrows(m);c:=ncols(m);for i in 1..r-1 repeat for j in 1..c-1 repeat if m(i,j)~=m(i+1,j+1)then return false;true)

m必须是允许〜=的某些元素的矩阵;解开它

f m ==
  r := nrows(m)
  c := ncols(m)
  for i in 1..(r - 1) repeat
    for j in 1..(c - 1) repeat
      if m(i,j)~=m(i + 1,j + 1)     then return(false)
  true

1

视网膜,148字节

m(1`\d+
$*#
1`#\n\d+\n
@
+`(#*)#@([^#\n]*(#*)\n)(.*)$
$1# $2$1@$4 #$3
@

+`##
# #
+(+s`^(\d+)\b(.*)^\1\b
$1$2#
s`.*^\d.*^\d.*
-1
)%`^[^- ]+ ?

\s+
1

在线尝试!

N×M输入矩阵

6 7 8 9 2 0
4 6 7 8 9 2
1 4 6 7 8 9
0 1 4 6 7 8

首先通过以下方式将对角线对齐将其转换为N×(N + M-1)矩阵:

# # # 6 7 8 9 2 0
# # 4 6 7 8 9 2 #
# 1 4 6 7 8 9 # #
0 1 4 6 7 8 # # #

然后重复检查第一列以包含一个唯一编号,如果是这样,则将其删除。如果输出为空白,则矩阵为Toeplitz。


哦,它不适用于负数,请解决此问题:)
eush77

1

MATL,11个字节

T&Xd"@Xz&=v

在线尝试!

前几个答案使用的直接的“构造Toeplitz矩阵并对照它”方法,使我感到无聊(看起来无论如何都会再长1个字节)。因此,我采用了“检查每个对角线仅包含一个唯一值”的方法。

T&Xd -提取输入的对角线并创建一个新的矩阵,将它们作为列(根据需要用零填充)

" -遍历该列

@Xz -推送迭代变量(当前列),并从中删除(填充)零

&=- 广播相等性检查 -如果所有剩余值彼此相等,则创建一个全为1(真)的矩阵,否则该矩阵包含一些0,这是虚假的

v -将结果值连接在一起,以创建一个最终结果向量,该向量为真值(全1)或假值(约0)



0

Clojure,94个字节

#(if(=(+ %2 %3 -1)(count(set(for[Z[zipmap][i r](Z(range)%)[j v](Z(range)r)][(- i j)v]))))1 -1)
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.