交互のサインマトリックス検証


16

交番符号行列であるnことにより、n数字からなるマトリックス-1、0、1、その結果:

  • 各行と列の合計は1です
  • 各行と列のゼロ以外のエントリは符号が交互になります

これらの行列は順列行列を一般化し、与えられnた行列の数はしばらくの間興味がありました。それらは、行列決定要因を計算するドッジソン凝縮法(ルイスキャロルとしてよく知られているチャールズドッジソンにちなんで命名)の間に自然に発生します。

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)

プログラムまたは機能について説明するnことによってn(行列n >= 1)-1,2、0と1の-出力truthy値与えられた行列場合は、交流符号行列、そうでなければ出力falsy値です。

これはなので、目標は使用するバイト数を最小限にすることです。

テストケース

次のテストケースは、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]]

回答:


3

網膜62 58 56 53バイト

バイトカウントはISO 8859-1エンコードを想定しており、\t実際のタブ(それ以外の場合はSEによってスペースに変換される0x09)に置き換える必要があります。

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

入力形式は、各列が右揃えの3つの文字を使用するマトリックスです。例:

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

出力は0(偽)または1(真実)のいずれかです。

テストスイート。(最初の数行は入力形式を変換し、Retinaに複数のテストケースを一度に実行させます。)

説明

ありがたいことに、入力は正方行列です。Retinaでは、正方形の転置はほぼ実行可能ですが、長方形の転置は大きな苦痛です。

$
\t$`¶

最初にタブを追加し、入力全体を再度追加します(プレフィックス$`を使用)。最後に改行を追加します(Retinaのエイリアスを使用します)。タブを使用して2つのコピーを分離しているため、コピーの1つを転置するときにそれらを区別できます。また、空白文字を使用することで、後で数バイトを節約できます。

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

これが最も扱いにくいビットです。行列の最初のコピーを転置します。アイデアは、最初のコピーのセルを一致させ、次に水平位置で(安定して)ソートすることです。セルを...(常に3文字幅であるため)一致させてから、後(.+)読みの内側で水平位置を測定します。次に、最初のコピーのみをトランスポーズすることを確認するために、タブを通過せずに文字列の先頭に到達できることを確認します。

.+タブを通過できるため、2番目のコピーの最初の行にある3バイトの文字列(セルと整列しない)にも一致することに気付くかもしれません。ただし、これらの一致の水平位置は最初のコピー内のどの位置よりも厳密に大きいため、これらの一致はその位置にとどまるため、これは問題ではありません。

残りは非常に簡単です:

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を満たします。

実際のテストでは、配列の累積合計を計算します。交番符号行列のため、結果は配列になり0「sおよび1」Sに終了する1

累積合計を逆にして重複を排除し、すべての一意の要素の最初の出現順序を維持します。真実の入力の場合、結果はリスト[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配列を受け入れ、真実または偽の配列を出力します。MATLでは、偽の結果には少なくとも1つのゼロ要素があるのに対し、真実の配列はすべてのゼロ以外の要素で構成されていることに注意することが重要です。以下は、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うーん、質問を読み違えたのは2回目です。(最初に関連するコメントはその後削除されました。)
ニール

ヘッダーは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で終了します。これはtruefalseであり、検証セクションで示されているように、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)]

test-suite.sh

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で終わるようにします(合計は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

有効交番符号行列に対して、出力が構成されます-1「sおよび0」sおよび-すべてのため-1以前相殺1ない他の数-およびその逆を。

一見すると、これは最後の列が1で終わる場合、チェックに失敗したように見えるかもしれません。ただし、k個のゼロを含むn×n行列の場合、有効な行にはn + k個の 1 が含まれます。最後を除くすべての列が同様に有効である場合、列にはn + k-1が存在しますが、これは不可能です。

他の数字がないことをテストするために、部分和を変数sに保存し、withで生成された行列の各エントリに対してそれらを更新しますs+=[n][s]

場合は、S = 0またはS = -1、これは同等ですs+=n。ただし、sの他のすべての値では、IndexErrorが発生するため、Pythonは終了コード1で直ちに終了します。これがどの時点でも発生しない場合、プログラムは終了コード0で正常に終了します。


0

R、54バイト

匿名関数は、デニスのPython 2、Jelly、およびJuliaの回答と同じロジックを使用します。

function(x)all(abs(cumsum(rbind(-1,cbind(t(x),x))))<2)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.