행렬이 1 순위입니까?


21

정수 행렬이 주어지면 순위가 1인지 테스트합니다. 즉, 모든 행이 동일한 벡터의 배수임을 의미합니다. 예를 들어

 2   0  -20  10  
-3   0   30 -15
 0   0   0   0

모든 행은의 배수입니다 1 0 -10 5.

동일한 정의가 행 대신 열에도 적용됩니다. 또는 곱셈 테이블과 같은 행렬은 순위가 1입니다.

 *    1   0  -10  5
    ----------------
 2 |  2   0  -20  10  
-3 | -3   0   30 -15
 0 |  0   0   0   0

각 행렬 항목 이로 대응되는 레이블의 곱이 되도록 행 레이블 r[i]과 열 레이블을 지정 했습니다 .c[j]M[i][j]M[i][j] = r[i] * c[j]

입력:

선택한 2D 컨테이너로서의 정수 매트릭스. 예를 들어 목록, 2D 배열 또는 이와 유사한 목록이 있습니다. 배열 형식에서 요구하지 않는 한 너비 또는 높이를 추가 입력으로 사용해서는 안됩니다.

매트릭스는 비 정사각형 일 수있다. 적어도 하나의 0이 아닌 항목이있을 것입니다. 비어 있거나 0 인 행렬을 다룰 필요는 없습니다.

정수로 인해 오버플로 문제가 발생하지 않는다고 가정 할 수 있습니다.

산출:

1 순위 행렬의 경우 일관된 값, 다른 행렬의 경우 일관된 다른 값

내장 :

당신은 하지 않을 수 있는 내장 계산해에 순위를 사용하거나 직접 순위를 확인합니다. 고유 값, 분해 등과 같은 다른 기본 제공 기능을 사용할 수 있지만 기본 제공 기능이없는 답변을 피투 트하는 것이 좋습니다.

테스트 사례 :

1 위 :

[[2, 0, -20, 10], [-3, 0, 30, -15], [0, 0, 0, 0]]
[[0, 0, 0], [0, 3, 0], [0, 0, 0]]
[[-10]]
[[0, 0, 0], [0, 4, 11], [0, -4, -11]]

1 위가 아님 :

[[-2, 1], [2, 4]]
[[0, 0, 3], [-22, 0, 0]]
[[1, 2, 3], [2, 4, 6], [3, 6, 10]]
[[0, -2, 0, 0], [0, 0, 0, 1], [0, 0, -2, 0]]

리더 보드 :


2
궁금한 점은 내장 MatrixRank@#==1&
함수를


2
아름다운 정리는 열 순위가 유한 차원 행렬의 행 순위와 동일하다는 것입니다.
Leaky Nun

3
부동 정밀도 문제에 대해 걱정해야합니까? 그들은 예를 들어 1 등급 행렬을 2 등급으로 보이게 할 수 있습니다.
Luis Mendo

@LuisMendo 고유 값 1.0000000001과 같은 정밀한 문제를 처리해야하지만 행렬이 크지 않고 잘못 분류되도록 특별히 선택되지 않았다고 가정 할 수 있습니다.
xnor

답변:


13

젤리 , 6 바이트

ẸÐfÆrE

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

작동 원리

ẸÐfÆrE  Main link. Argument: M (2D array)

ẸÐf     Filter by any, removing rows of zeroes.
   Ær   Interpret each row as coefficients of a polynomial and solve it over the
        complex numbers.
     E  Test if all results are equal.

정도

Ær수치 방법을 사용하므로 결과가 정확하지 않습니다. 예를 들어, 다항식 6-5x + x² 를 나타내는 입력 [6, -5, 1] 은 근이 3.00000000000000041.9999999999999998이 됩니다. 그러나 다항식의 모든 계수에 동일한 0이 아닌 상수를 곱하면 똑같이 부정확 한 근이 발생합니다. 예를 들어, 동일한 루트를 얻는다 [6, -5, 1][6 × 10 100 -5 × 10 100 10 100 ] .Ær

floatcomplex 유형 의 정밀도가 제한되어 있으면 오류가 발생할 있습니다. 예를 들어 [1, 1][10 100 , 10 100 + 1]에Ær 대해 동일한 근을 구합니다 . 이후 우리는 매트릭스 잘못 분류 될 크고 특별히 선택하지없는 가정 할 수있다 , 즉 미세해야한다.


5
다항식의 모든 계수에 동일한 0이 아닌 상수를 곱하면 똑같이 부정확 한 근 이 발생합니다.
Luis Mendo

8

하스켈 , 50 바이트

r목록 목록 소요 Integer의 반환을 False행렬은 순위 하나가있는 경우, True그렇지.

r l=or[map(x*)b<map(y*)a|a<-l,b<-l,(x,y)<-zip a b]

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

작동 원리

  • 행의 모든 쌍을 생성 a하고 b(동일한 행을 포함), 및 각각의 쌍에 대해, 수 xy대응하는 요소들을 실행.
  • 곱 행 b함으로써 x및 행 a에 의해 y. 결과가 항상 같은 경우에만 행렬의 순위가 1이됩니다.
  • 쌍은 두 가지 순서로 생성되므로 < 불평등이 있는지 확인하는 데 사용할 수 있습니다. 시험 결과의리스트와 결합되어 or제공 True비 비례 행이 경우.

7

매스 매 티카, 51 33 바이트

RowReduce@#~Count~Except@{0..}<2&

입력

[{{2,0, -20,10}, {-3,0,30, -15}, {0,0,0,0}}]

사용자의 -14 바이트 202729 정환 민에서
3 바이트 더 절약


길이가 인 테이블을 생성하는 대신 0에 곱하기가 0이고 곱하기를 나열 First@#할 수 있으므로 계산할 수 있습니다 0First@#. 또한 Tr[1^<list>]목록의 길이를 계산하는 데 사용할 수도 있습니다 .
user202729

편집 할게요!
J42161217

대신 0#&@@#, {0..}너무 작동합니다. 그런 다음 Infix작동하므로 최종 코드는 RowReduce@#~Count~{0..}==Tr[1^#]-1&2 바이트를 절약 할 수 있습니다 .
JungHwan Min

실제로 물건을 Except제거하는 데 사용할 수 있습니다 Tr. -3 바이트 :RowReduce@#~Count~Except@{0..}==1&
JungHwan Min

행 축소 행렬은 원래 행렬이 0이 아니기 때문에 0이 아닌 것으로 보장되므로 카운트 결과는 양의 정수가되므로 <2대신 사용할 수 있습니다 ==1.
user202729

4

자바 스크립트 (ES6), 68 67 65 바이트

이것은 Neil의 05AB1E 답변을 기반으로합니다. 하며 원래의 접근 방식보다 훨씬 효율적입니다.

반환 false순위 하나에 대한 true그렇지 않으면.

f=(a,R,V,X)=>a.some(r=>r.some((v,x)=>R?v*V-r[X]*R[x]:f(a,r,v,x)))

테스트 사례


원래 답변, 84 바이트

반환 false순위 하나에 대한 true그렇지 않으면.

a=>a.some(r=>r.some((x,i)=>(isNaN(x/=a.find(r=>r.some(x=>x))[i])?r:1/r[0]?r=x:x)-r))

테스트 사례

방법?

a => a.some(r =>          // given a matrix a, for each row r of a:
  r.some((x, i) =>        //   for each value x of r at position i:
    (                     //
      isNaN(x /=          //     divide x by a[ref][i]
        a.find(r =>       //       where ref is the index of the first row that
          r.some(x => x)  //       contains at least one non-zero value
        )[i]              //       (guaranteed to exist by challenge rules)
      ) ?                 //     we get NaN for 0/0, in which case:
        r                 //       use r, so that this column is ignored
      :                   //     else:
        1 / r[0] ?        //       if r is still holding the current row:
          r = x           //         set it to x (either a float, +Inf or -Inf)
        :                 //       else:
          x               //         use x
    ) - r                 //     subtract r from the value set above (see table)
  )                       //   end of some()
)                         // end of every()

코드의 끝에서 수행되는 빼기는 다음과 같이 여러 가지 상황으로 이어질 수 있습니다.

A                   | B              | A - B       | False / True
--------------------+----------------+-------------+-------------
array of 1 number   | same array     | 0           | False
array of 2+ numbers | same array     | NaN         | False
a number            | same number    | 0           | False
+Infinity           | +Infinity      | NaN         | False
-Infinity           | -Infinity      | NaN         | False
a number            | another number | <> 0        | True
+Infinity           | -Infinity      | +Infinity   | True
-Infinity           | +Infinity      | -Infinity   | True
a number            | +/-Infinity    | +/-Infinity | True
+/-Infinity         | a number       | +/-Infinity | True

실제 값을 얻 자마자 테스트가 실패합니다. 이는 행렬의 모든 행 y 에서 a (i, y)a (i, r) 사이에 두 가지 다른 비율 ( 0 / 0 이외)이 발생할 때 발생 합니다. r 은 0이 아닌 행의 인덱스입니다.


허, 나는 단지 그 자신을 궁금해하고 있었다 ...
Neil

@Neil 새 답변으로 게시 하시겠습니까? 바로 알려주세요.
Arnauld


3

젤리 , 12 바이트

ẸÐfµ÷"ЀZE€Ẹ

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

설명

ẸÐfµ÷"ЀZE€Ẹ  Main link
 Ðf           Filter; keep all elements where
Ẹ             At least one element is truthy (remove zero-rows)
      Ѐ      For each row on the right side
    ÷"        Divide it by each row in the original
        Z     Zip the array
          €   For each submatrix
         E    Are all rows equal?
           Ẹ  Is at least one of the elements from above truthy?

이것이 원래 알고리즘의 마일 골프에 대한 나의 해석이므로 설명이 약간 잘못되었을 수 있습니다

마일로 인해 -5 바이트


... 코드가 돈에 중독되어 있습니다. (I 'm getting deja vu ...)
완전히 인간적인

@icrieverytim 이봐, 적어도 달러 부호의 수는 이번에는 코드 길이의 절반보다 작습니다! : P
HyperNeutrino

1
P : @icrieverytim 이제 버그, 심지어 적은 달러 기호 고정
HyperNeutrino

나는이 12도 작동한다고 생각하는 것은 바이트 ẸÐfµ÷"ЀZE€Ẹ TIO
마일

@ 마일리지 오! 귀하의 접근 방식은 약간 다릅니다 (제 생각에?). 당신이 원하는 답변을 게시 할 수 있습니다 :)
HyperNeutrino

3

05AB1E , 16 바이트

2ãεø2ãε`R*`Q}W}W

온라인으로 사용해보십시오! 사각형의 반대쪽 모서리에 같은 곱이있는 곱셈표 속성을 사용합니다. 설명:

2ãε           }     Loop over each pair of rows
   ø                Transpose the pair into a row of pairs
    2ãε     }       Loop over each pair of columns
       `R*`Q        Cross-multiply and check for equality
             W W    All results must be true

3

TI 기본 (TI-83 시리즈), 28 27 28 바이트 (62 자)

:Prompt [A]
:{0→X
:Matr►list(ref([A])ᵀ,L₁,X
:not(max(abs(ᶫX

행렬의 행-에 첼론 형식을 계산 [A]하고 첫 번째 행 (삭제)을 저장 L₁하고 두 번째 행을에 저장 ᶫX합니다. 그런 다음 max(abs(ᶫX0 ᶫX으로 만 구성된 경우 0이되고, 그렇지 않으면 양수 값이 not(됩니다. 행렬의 순위가 1이면 1로, 그렇지 않으면 0입니다.

1 행 행렬의 경우 ᶫX로 설정되고 행렬 {0}의 존재하지 않는 두 번째 행을 보려고 할 때 변경되지 않습니다.


Scott Milner 덕분에 -1 바이트

1 행 행렬의 차원 오류를 수정하기 위해 +1 바이트 행이 하나만있는 행렬에서 두 번째 행을 추출하려고 하면 Matr►list( 명령이 불평합니다. 그러나 행렬에서 첫 번째와 두 번째 행을 모두 추출하려고하면 자동으로 실패합니다.


1
Prompt [A]대신에 바이트를 저장할 수 있습니다 Ans→[A].
Scott Milner

@ScottMilner 감사합니다! ClrListinitialize 와 같은 것을 사용하면 피할 수있는 방법이있을 것입니다. ᶫX그러나 더 적은 공간에서 작동한다는 것을 얻지 못했습니다.
Misha Lavrov

Matr►list(목록이 존재하지 않더라도 목록을 덮어 쓰므로 두 번째 행을 제거 하면 5 바이트가 절약됩니다.
kamoroso94

1
@ kamoroso94 두 번째 줄의 점은 존재하지 않을 때 목록을 만들지 않는 것입니다. 두 번째 줄의 점은 행렬에 행이 하나만있을 때 두 번째 행의 기본값을 만드는 것입니다. 두 번째 줄을 없애면 1xN 행렬에 대해 코드가 충돌합니다.
미샤 라브 로프

2
@ kamoroso94 L1을 Y가 아닌 ᶫY로 바꿔야합니다. 그렇지 않으면 계산기는 "첫 번째 행을 ᶫY로 추출하고 두 번째 행을 ᶫX로 추출하지 않음"이 아니라 "행렬의 Y 번째 행을 ᶫX로 추출"이라고 생각합니다.
Misha Lavrov

3

Brachylog , 27 바이트

{⊇Ċ}ᶠzᵐ{↰₁ᶠ{⟨hz{t↔}⟩×ᵐ=}ᵐ}ᵐ

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

"각 직사각형의 반대쪽 모서리에있는 제품은 같아야합니다"라는 Neil의 접근 방식을 사용합니다. 교차 곱은 비용이 많이 들고 10 바이트 전체를 차지하지만, 이것은 문제의 진실성과 허위에 대한 두 가지 일관된 출력을 규정하기 때문에 시도한 모든 부서 기반 접근법보다 여전히 짧습니다 false.. 0으로 나누기 오류로 너무 많은 바이트를 사용합니다.

{⊇Ċ}ᶠzᵐ{↰₁ᶠ{⟨hz{t↔}⟩×ᵐ=}ᵐ}ᵐ
{⊇Ċ}ᶠ                        Get each pair of rows from the matrix
                             eg.: [ [[a, b, c], [k, l, m]], ... ]
     zᵐ                      Zip each pair's elements
                                  [ [[a, k], [b, l], [c, m]], ... ]
       {                 }ᵐ  Map this over each pair of rows:
                                  [[a, k], [b, l], [c, m]]
        ↰₁ᶠ                  Get each pair of paired elements from the rows
                                  [[[a, k], [b, l]], [[b, l], [c, m]], [[a, k], [c, m]]]
           {           }ᵐ    Map this over each pair of pairs
                                  [[a, k], [b, l]]
            ⟨hz{t↔}⟩         Zip the first pair with the reverse of the second
                                  [[a, l], [k, b]]
                    ×ᵐ       Multiply within each sublist
                                  [al, kb]
                      =      The results should be equal
                             (If the results are unequal for any pair, the whole predicate fails,
                              and outputs false.)

요소 별 구분을 기반으로하는 대체 접근 방식 ( 30 바이트 )를 :

{≡ᵉ¬0&}ˢ\↰₁ˢ{c׬0&⟨hz∋⟩ᶠ/ᵐ²=ᵐ}

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



1

SageMath, 40 바이트

lambda M:any(M.rref()[1:])*(M.nrows()>1)

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

이 익명 함수는 False행렬이 순위가 1이면 True그렇지 않으면를 반환합니다.

이 함수는 행렬 M을 입력으로 사용 하여 행렬 을 축소 된 행-에 첼론 형식 ( M.rref())으로 변환 any하고 첫 번째가 0이 아닌 행을 테스트 합니다. 그런 다음 그 값에 곱합니다 M.nrows()>1(행렬에 둘 이상의 행이 있습니까?).


1

파이썬 3 , 93 91 바이트

lambda m,e=enumerate:any(h*g-r[j]*s[i]for r in m for i,h in e(r)for s in m for j,g in e(s))

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

작동 원리

2 차 소수에 0이 아닌 결정자가 있는지 확인합니다. 이 경우 순위는 2 이상이어야합니다. "비 소멸 형 p- 마이너 (0이 아닌 결정자를 갖는 p × p 서브 ​​매트릭스)는 해당 서브 매트릭스의 행과 열이 선형으로 독립되어 있음을 나타냅니다. 전체 행렬의 열은 선형 적으로 독립적이므로 (전체 행렬에서) 행과 열의 순위는 적어도 결정적 순위만큼 크다 "( Wikipedia에서 )

참고 : user71546의 의견 덕분에 2 바이트를 줄였습니다.


1
f=lambda m,e=enumerate:any(h*g-r[j]*s[i]for r in m for i,h in e(r)for s in m for j,g in e(s))
91-

감사합니다! 했어요!
Luca Citi

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.