交替符号矩阵验证


16

一个交替的符号矩阵nn组成的数字矩阵-1,0,1,使得:

  • 每行和每一列的总和为1
  • 每行和每列中的非零条目以符号交替

这些矩阵概括了置换矩阵,并且对于给定n的时间,此类矩阵的数量令人关注。它们在计算矩阵行列式的Dodgson凝聚方法(以Charles Dodgson命名,更名为Lewis Carroll)中自然发生。

以下是4 x 4交替符号矩阵的一些示例:

 0  1  0  0          1  0  0  0          0  0  1  0          0  0  1  0    
 0  0  1  0          0  0  1  0          0  1 -1  1          1  0 -1  1
 1  0  0  0          0  1 -1  1          1 -1  1  0          0  1  0  0
 0  0  0  1          0  0  1  0          0  1  0  0          0  0  1  0

以下是4 x 4矩阵的一些示例,这些矩阵不是交替的符号矩阵:

 0  1  0  0
 0  0  0  1
 1  0  0  0
 0  0  1 -1    (last row and last column don't add to 1)

 0  0  0  1
 1  0  0  0
-1  1  1  0
 1  0  0  0    (third row does not alternate correctly)

您的程序或函数将由-1s,0s和1s 的nby n矩阵(n >= 1)给出- 如果给定矩阵是交替符号矩阵,则输出真实值,否则输出伪值。

这是,因此目标是最大程度地减少使用的字节数。

测试用例

以下测试案例以类似Python的2D列表格式给出。

真相:

[[1]]
[[1,0],[0,1]]
[[0,1],[1,0]]
[[0,1,0],[0,0,1],[1,0,0]]
[[0,1,0],[1,-1,1],[0,1,0]]
[[0,1,0,0],[0,0,1,0],[1,0,0,0],[0,0,0,1]]
[[1,0,0,0],[0,0,1,0],[0,1,-1,1],[0,0,1,0]]
[[0,0,1,0],[0,1,-1,1],[1,-1,1,0],[0,1,0,0]]
[[0,0,1,0],[1,0,-1,1],[0,1,0,0],[0,0,1,0]]
[[0,0,1,0,0],[0,1,-1,1,0],[1,-1,1,0,0],[0,1,0,-1,1],[0,0,0,1,0]]
[[0,0,1,0,0,0,0,0],[1,0,-1,0,1,0,0,0],[0,0,0,1,-1,0,0,1],[0,0,1,-1,1,0,0,0],[0,0,0,0,0,0,1,0],[0,0,0,0,0,1,0,0],[0,1,-1,1,0,0,0,0],[0,0,1,0,0,0,0,0]]
[[0,0,0,0,1,0,0,0],[0,0,1,0,-1,1,0,0],[0,0,0,1,0,0,0,0],[1,0,0,-1,1,-1,1,0],[0,1,-1,1,-1,1,0,0],[0,0,0,0,1,0,0,0],[0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1]]

虚假:

[[0]]
[[-1]]
[[1,0],[0,0]]
[[0,0],[0,1]]
[[-1,1],[1,0]]
[[0,1],[1,-1]]
[[0,0,0],[0,0,0],[0,0,0]]
[[0,1,0],[1,0,1],[0,1,0]]
[[-1,1,1],[1,-1,1],[1,1,-1]]
[[0,0,1],[1,0,0],[0,1,-1]]
[[0,1,0,0],[0,0,0,1],[1,0,0,0],[0,0,1,-1]]
[[0,0,1,0],[0,0,1,0],[1,0,-1,1],[0,1,0,0]]
[[0,0,0,1],[1,0,0,0],[-1,1,1,0],[1,0,0,0]]
[[1,0,1,0,-1],[0,1,0,0,0],[0,0,0,0,1],[0,0,0,1,0],[0,0,0,0,1]]
[[0,0,1,0,0],[0,1,-1,1,0],[1,-1,1,0,0],[0,1,1,-1,0],[0,0,-1,1,1]]
[[0,-1,0,1,1],[1,-1,1,-1,1],[0,1,1,0,-1],[1,1,-1,1,-1],[-1,1,0,0,1]]
[[0,0,1,0,0,0,0,0],[1,0,1,0,1,0,0,0],[0,0,0,1,-1,0,0,1],[0,0,1,-1,1,0,0,0],[0,0,0,0,0,0,1,0],[0,0,0,0,0,1,0,0],[0,1,-1,1,0,0,0,0],[0,0,1,0,0,0,0,0]]

Answers:


3

视网膜62 58 56 53字节

字节计数采用ISO 8859-1编码,\t应将其替换为实际的制表符(否则将被SE转换为空格的0x09)。

$
\t$`¶
O$#`...(?<=^[^\t]*(.+))
$.1
T` 0
^(1(-11)*\s)+$

输入格式是一个矩阵,其中每列使用三个右对齐字符,例如:

  0  0  1  0
  1  0 -1  1
  0  1  0  0
  0  0  1  0

输出为0(虚假)或1(真实)。

测试套件。(前几行会转换输入格式,并让Retina一次运行多个测试用例。)

说明

值得庆幸的是,输入是一个正方形矩阵:在Retina中对正方形进行转置几乎是可行的,而对矩形进行转置则是一个巨大的难题。

$
\t$`¶

我们首先添加一个选项卡,再次添加整个输入(使用前缀$`),然后在末尾添加换行符(使用Retina的alias )。我们使用制表符将两个副本分开,以便在转置一个副本时可以区分它们,并且通过使用空格字符,我们可以在以后保存几个字节。

O$#`...(?<=^[^\t]*(.+))
$.1

这是最棘手的位:转置矩阵的第一个副本。想法是匹配第一个副本中的单元格,然后按水平位置对其进行(稳定)排序。我们将单元格与之匹配...(因为它们始终为三个字符宽),然后使用后向(.+)内部测量水平位置。然后,为确保仅转置第一个副本,请检查是否可以到达字符串的开头而无需移至制表符。

您可能会注意到,这还将匹配第二个副本的第一行中的某些三字节字符串(甚至与单元格都不对齐),因为.+可以通过选项卡。但是,这不是问题,因为这些匹配项的水平位置严格大于第一份副本中的任何位置,因此这些匹配项将保持其位置。

其余的很简单:

T` 0

我们从输入中删除空格和零。

^(1(-11)*\s)+$

最后,我们检查整个输入由形式的空白封端的行的1(-11)*,即的交替序列1-1该开始和结束1(因为否则它不总和为1)。


3

果冻,15个字节

;Zḟ€0;€-;@€-IFP

在线尝试!

;Zḟ€0;€-;@€-IFP   Main monadic chain. Argument: z

;Z                Concatenate with its transpose.
  ḟ€0             Remove zeros from each sub-list. At this point,
                  one expects lists of the form [1, -1, 1, -1, ..., 1] for truthy,
                  and any other arrays containing purely 1 and -1 for falsey.
     ;€-          Append -1 to each sub-list.
        ;€@-      Prepend -1 to each sub-list.
            I     Compute the difference between each term. At this point,
                  for truthy, one expects arrays filled with 2, and arrays
                  containing 0 otherwise.
             FP   Product of every item. This checks if any item is equal to zero.

3

Pyth,16个字节

!sm-sM._+d_1U2+C

在线尝试:演示测试套件

说明:

!sm-sM._+d_1U2+CQQ   two implicit Qs (=input matrix) at the end
              +CQQ   zip Q and connect it with Q (=list of columns and rows)
  m                  map each column/row d to:
        +d_1            append -1 to d
      ._                compute all prefixes of ^
    sM                  compute the sums of the prefixes
   -        U2          remove zeros and ones
                        a column/row is correct, if this gives an empty list 
 s                   connect up all resulting lists
!                    check, if this result is empty

3

果冻,11 字节

;Zj-+\ṚQḄ=2

对于交替的符号矩阵,返回1,否则返回0在线尝试!验证所有测试用例

背景

忽略零,每一行和每一列都必须由模式(1,-1)* 1组成,即交替出现的1-1,以1开头和结尾(因此总和为1)。

为了验证这种情况,我们采用所有行和列的数组,并使用-1作为分隔符将它们连接起来。由于所有端点均为1,因此当且仅当行和列都满足时,所得的平面数组才能满足模式(1,-1)* 1

对于实际测试,我们计算数组的累加和。对于交替符号矩阵,结果将是一个以1结束的01的数组。

我们反转累积总和并进行重复数据删除,以保持所有唯一元素初次出现的顺序。对于真实输入,结果将是列表[1,0]

为了输出相应的布尔值,我们将重复的累积和从二进制转换为整数,然后测试结果是否为2

怎么运行的

;Zj-+\ṚQḄ=2  Main link. Argument: M (matrix / 2D array)

 Z           Zip; transpose M's rows and columns.
;            Concatenate M and zipped M.
  j-         Join, separating by -1.
    +\       Take the cumulative sum of the result.
      Ṛ      Reverse the array of partial sums.
       Q     Unique; deduplicate the partial sums.
        Ḅ    Unbinary; convert from base 2 to integer.
         =2  Test for equality with 2.

2

MATL,18 16 15 13字节

@Luis节省了3个字节

t!h"@s1=@Xzdv

该解决方案接受2D数组作为输入,并将输出一个true或false数组。重要的是要注意,在MATL中,真值数组由所有非零元素组成,而假结果至少具有一个零元素。这是true / falsey数组的另一个示例

在线尝试

修改后的版本可以显示所有测试用例

说明

        % Implicitly grab input matrix
t!      % Duplicate and transpose input
h       % Horizontally concatenate input with transpose. This allows us to 
        % process only columns since now the columns *also* contain the rows.
"       % For each column (of our column/row combined matrix)
  @s1=  % Compute the sum and ensure it is equal to 1
  @Xz   % Get the non-zeros
  d     % Compute the element-to-element difference. The 1 and -1 alternate only if
        % all these differences are non-zero
  v     % Vertically concatenate everything on the stack
        % Implicit end of loop and implicitly display truthy/falsey value


1

的JavaScript(ES6),112个 100字节

a=>!/(^|,)(?!0*10*(-10*10*)*(,|$))/.test(a.map(b=>b.join``)+','+a.map((_,i)=>a.map(b=>b[i]).join``))

展平数组及其转置为字符串,然后(忽略0s)检查1-11...1-11每个字符串中的模式。

编辑:由于@PeterTaylor,节省了12个字节。


1
您无需检查该模式,-11-1...-11-1因为既然条目交替且具有正和,则必须1多于个-1,因此该模式必须为1-11...1-11
彼得·泰勒

@PeterTaylor Ugh,那是我第二次误解这个问题。(此后有关第一次的评论已删除。)
Neil

头说,110个字节,但它只有100
彼得·泰勒

1
@PeterTaylor至少“由于@PeterTaylor而节省了12个字节”是正确的。
尼尔

1

Python 2,63 60字节

s=0;x=input()
for r in x+zip(*x):
 for n in(-1,)+r:s+=[n][s]

输入是元组列表。

它以退出代码 0(用于替换符号矩阵)终止,否则退出代码1。这是真实的虚假的待办事项和-如图所示验证部分-它的确可以用作一个条件,例如,一个bash脚本。

验证

test-cases.txt

[(1,)]
[(1, 0), (0, 1)]
[(0, 1), (1, 0)]
[(0, 1, 0), (0, 0, 1), (1, 0, 0)]
[(0, 1, 0), (1, -1, 1), (0, 1, 0)]
[(0, 1, 0, 0), (0, 0, 1, 0), (1, 0, 0, 0), (0, 0, 0, 1)]
[(1, 0, 0, 0), (0, 0, 1, 0), (0, 1, -1, 1), (0, 0, 1, 0)]
[(0, 0, 1, 0), (0, 1, -1, 1), (1, -1, 1, 0), (0, 1, 0, 0)]
[(0, 0, 1, 0), (1, 0, -1, 1), (0, 1, 0, 0), (0, 0, 1, 0)]
[(0, 0, 1, 0, 0), (0, 1, -1, 1, 0), (1, -1, 1, 0, 0), (0, 1, 0, -1, 1), (0, 0, 0, 1, 0)]
[(0, 0, 1, 0, 0, 0, 0, 0), (1, 0, -1, 0, 1, 0, 0, 0), (0, 0, 0, 1, -1, 0, 0, 1), (0, 0, 1, -1, 1, 0, 0, 0), (0, 0, 0, 0, 0, 0, 1, 0), (0, 0, 0, 0, 0, 1, 0, 0), (0, 1, -1, 1, 0, 0, 0, 0), (0, 0, 1, 0, 0, 0, 0, 0)]
[(0, 0, 0, 0, 1, 0, 0, 0), (0, 0, 1, 0, -1, 1, 0, 0), (0, 0, 0, 1, 0, 0, 0, 0), (1, 0, 0, -1, 1, -1, 1, 0), (0, 1, -1, 1, -1, 1, 0, 0), (0, 0, 0, 0, 1, 0, 0, 0), (0, 0, 1, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 1)]
[(0,)]
[(-1,)]
[(1, 0), (0, 0)]
[(0, 0), (0, 1)]
[(-1, 1), (1, 0)]
[(0, 1), (1, -1)]
[(0, 0, 0), (0, 0, 0), (0, 0, 0)]
[(0, 1, 0), (1, 0, 1), (0, 1, 0)]
[(-1, 1, 1), (1, -1, 1), (1, 1, -1)]
[(0, 0, 1), (1, 0, 0), (0, 1, -1)]
[(0, 1, 0, 0), (0, 0, 0, 1), (1, 0, 0, 0), (0, 0, 1, -1)]
[(0, 0, 1, 0), (0, 0, 1, 0), (1, 0, -1, 1), (0, 1, 0, 0)]
[(0, 0, 0, 1), (1, 0, 0, 0), (-1, 1, 1, 0), (1, 0, 0, 0)]
[(1, 0, 1, 0, -1), (0, 1, 0, 0, 0), (0, 0, 0, 0, 1), (0, 0, 0, 1, 0), (0, 0, 0, 0, 1)]
[(0, 0, 1, 0, 0), (0, 1, -1, 1, 0), (1, -1, 1, 0, 0), (0, 1, 1, -1, 0), (0, 0, -1, 1, 1)]
[(0, -1, 0, 1, 1), (1, -1, 1, -1, 1), (0, 1, 1, 0, -1), (1, 1, -1, 1, -1), (-1, 1, 0, 0, 1)]
[(0, 0, 1, 0, 0, 0, 0, 0), (1, 0, 1, 0, 1, 0, 0, 0), (0, 0, 0, 1, -1, 0, 0, 1), (0, 0, 1, -1, 1, 0, 0, 0), (0, 0, 0, 0, 0, 0, 1, 0), (0, 0, 0, 0, 0, 1, 0, 0), (0, 1, -1, 1, 0, 0, 0, 0), (0, 0, 1, 0, 0, 0, 0, 0)]

测试套件

while read; do
        if python2 asmv.py <<< "$REPLY"; then
                echo "true"
        else
                echo "false"
        fi
done < test-cases.txt 2>&- | uniq -c

输出量

$ bash test-suite.sh
     12 true
     17 false

怎么运行的

忽略零,每一行和每一列都必须由模式(1,-1)* 1组成,即交替出现的1-1,以1开头和结尾(因此总和为1)。

为了验证这种情况,我们对输入矩阵M进行 zip /转置,将结果附加到M(现在由行和列的列表组成),并在每个行/列前添加-1

例如,如果M是以下矩阵之一(有效,无效)

     0  1  0         0  0  0
     0  0  1         1  0  0
     1  0  0         0  1 -1

结果是

-1 | 0  1  0    -1 | 0  0  0
-1 | 0  0  1    -1 | 1  0  0
-1 | 1  0  0    -1 | 0  1 -1
------------    ------------
-1 | 0  0  1    -1 | 0  1  0
-1 | 1  0  0    -1 | 0  0  1
-1 | 0  1  0    -1 | 0  0 -1

逐行读取生成的矩阵必须得到模式为(-1,1)*的平面序列。为了验证这种情况,我们从第一行开始取所有条目的累加总和。

对于示例矩阵,结果为

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

对于有效的交替符号矩阵,输出将包含-10以及–因为每-1抵消了前一个1,反之亦然-因此,其他任何数字都不会。

乍一看,这似乎无法检查最后一列是否以1结尾。但是,对于包含k个零的n×n矩阵,有效行将包含n + k个。如果除最后一个列以外的所有列均有效,则列中将有n + k-1个列,这是不可能的。

为了测试没有其他数字,我们将部分和存储在变量s中并使用生成矩阵的每个项更新它们s+=[n][s]

如果s = 0s = -1,则等效于s+=n。但是,对于s的所有其他值,它将导致IndexError,因此Python立即以退出代码1终止。如果这在任何时候都没有发生,则程序将以退出代码0干净地结束。


0

R,54个字节

匿名函数使用与Dennis的Python 2,Jelly和Julia答案相同的逻辑。

function(x)all(abs(cumsum(rbind(-1,cbind(t(x),x))))<2)
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.