대체 부호 행렬 검증


16

교대 부호 행렬n의해 n숫자로 이루어진 매트릭스 -1, 0, 1이되도록 :

  • 각 행과 열의 합은 1
  • 각 행과 열의 0이 아닌 항목은 대체 부호

이 행렬은 순열 행렬을 일반화하고 주어진 행렬의 수는 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)

프로그램이나 함수가 부여된다 n의해 n매트릭스 ( n >= 1출력 - -1s, 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하고 실제 탭으로 대체해야합니다 (0x09는 그렇지 않으면 SE로 공백으로 바 turned).

$
\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 's alias 사용 )을 추가합니다. 우리는 탭을 사용하여 두 사본을 분리하여 사본 중 하나를 옮길 때 구별 할 수 있으며 공백 문자를 사용하여 나중에 몇 바이트를 절약 할 수 있습니다.

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

이것은 가장 까다로운 비트입니다. 행렬의 첫 번째 사본을 바꿉니다. 아이디어는 첫 번째 사본의 셀을 일치시킨 다음 수평 위치로 (안정적으로) 정렬하는 것입니다. 셀 ...은 항상 3 자이므로 셀을 일치시킨 다음 (.+)lookbehind 내부에서 가로 위치를 측정합니다 . 그런 다음 첫 번째 사본 만 바꾸려면 탭을 지나치지 않고 문자열의 시작 부분에 도달 할 수 있는지 확인합니다.

.+탭을 통과 할 수 있기 때문에 두 번째 사본의 첫 번째 행에있는 일부 3 바이트 문자열 (셀과도 정렬되지 않음)과 일치한다는 것을 알 수 있습니다 . 그러나 이러한 일치 항목의 가로 위치가 첫 번째 사본 내부의 가로 위치보다 엄청 나기 때문에 이러한 문제는 해당 위치에 남아 있지 않기 때문에 문제가되지 않습니다.

나머지는 매우 간단합니다.

T` 0

입력에서 공백과 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

반환 기호 행렬, 교대 0 , 그렇지. 온라인으로 사용해보십시오!또는 모든 테스트 사례를 확인 .

배경

제로를 무시하고, 각 행과 열은 패턴을 구성한다 (1, -1) * (1) 의, 즉, 교류 발생 1-1 , 시작하고 끝나는 1 (따라서 합계 것은 1 ).

이 경우를 확인하기 위해 모든 행과 열의 배열을 가져 와서 -1 을 구분 기호로 사용하여 결합합니다 . 모든 끝 점이 1 이므로 결과 평면 배열은 패턴을 만족시킵니다. (1, -1) * 1을 은 행과 열이 수행하는 경우에만 .

실제 테스트에서는 배열의 누적 합계를 계산합니다. 교류 부호 행렬의 결과의 배열 될 것이다 0 의 그리고 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에서, 진리 배열은 0이 아닌 모든 요소로 구성되고 거짓 결과에는 적어도 하나의 0 요소가 있습니다. 다음은 진실 / 거짓 배열의 또 다른 데모입니다 .

온라인으로 사용해보십시오

모든 테스트 사례를 표시하도록 수정 된 버전

설명

        % 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

자바 스크립트 (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에 불과합니다
Peter Taylor

1
@PeterTaylor 최소한 "@PeterTaylor 덕분에 저장된 12 바이트"는 정확했습니다.
Neil

1

파이썬 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)]

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

작동 원리

0을 무시하면 각 행과 열은 패턴 (1, -1) * 1 , 즉 12가 번갈아 발생해야합니다. -1 , 시작하고 끝나는 1 합인 (그래서 1 ).

이 경우를 확인하기 위해 입력 행렬 M을 압축 / 조치합니다. 결과를 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 의와 의와 - 모든 이후 -1 이전 상쇄 다른 번호 -와 반대의 반대를.

언뜻 보면, 마지막 열이 1로 끝나는 지 확인하지 못하는 것처럼 보일 수 있습니다 . 그러나 k 개의 0을 포함 하는 n × n 행렬의 경우 유효한 행에는 n + k 가 포함 됩니다. 마지막 열을 제외한 모든 열도 유효하면 열에 n + k-1 열이있어 불가능합니다.

다른 숫자가 없음을 테스트하려면, 우리는 변수에 부분합 저장 과 생성 행렬의 각 항목에 대해을 업데이트 s+=[n][s].

경우 S = 0 또는 S = -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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.