재귀 2x2 결정 요인


17

2x2 행렬의 결정 요인

a b
c d

에 의해 제공됩니다 ad - bc.

크기가 2 n x 2 n , n ≥ 1 인 자릿수 행렬이 주어지면 단일 숫자에 도달 할 때까지 각 2 x 2 서브 블록의 결정자를 재귀 적으로 계산하여 얻은 결과를 출력합니다.

예를 들어, 입력이 주어지면

3 1 4 1
5 9 2 6
5 3 5 8
9 7 9 3

한 단계 후에 우리는 다음을 얻습니다.

(3*9 - 1*5)    (4*6 - 1*2)    =    22  22
(5*7 - 3*9)    (5*3 - 8*9)         8  -57

그리고 다시 한 번 반복하면 다음과 같은 결과를 얻습니다.

(22*-57 - 22*8) = -1430

따라서 출력은이어야합니다 -1430.

규칙

  • 행렬의 요소는 항상 한 자리 정수입니다 (예 : 0-9).
  • 데이터의 전처리가 수행되지 않는 한 편리한 목록 또는 문자열 형식으로 입력 할 수 있습니다. 행렬은 항상 정사각형이므로 원하는 경우 2D 목록 대신 단일 1D 목록으로 입력 할 수 있습니다.
  • 함수 입력, STDIN, 명령 줄 인수 또는 가장 가까운 대안을 통해 입력 할 수 있습니다.
  • 출력은 기능 출력, STDOUT 또는 가장 가까운 대안으로 기능하기위한 단일 정수 여야합니다. 목록 또는 행렬에서 단일 정수를 출력 할 수 없습니다.
  • 언어가 지원하는 경우 내장 결정자 및 행렬 조작 방법을 사용할 수 있습니다.
  • 유효한 입력을 위해서는 알고리즘이 이론적으로 작동해야합니다.
  • 표준 규칙이 적용됩니다.

테스트 사례

다음 테스트 사례는 Python 스타일 목록으로 제공됩니다.

[[1,0],[0,1]] -> 1
[[1,9],[8,4]] -> -68
[[0,1,2,3],[4,5,6,7],[8,9,0,1],[2,3,4,5]] -> 40
[[3,1,4,1],[5,9,2,6],[5,3,5,8],[9,7,9,3]] -> -1430
[[9,0,0,9],[0,9,9,0],[9,0,9,0],[0,9,0,9]] -> 13122
[[1,0,0,0,0,0,0,0],[2,1,0,0,0,0,0,0],[3,2,1,0,0,0,0,0],[4,3,2,1,0,0,0,0],[5,4,3,2,1,0,0,0],[6,5,4,3,2,1,0,0],[7,6,5,4,3,2,1,0],[8,7,6,5,4,3,2,1]] -> 1
[[7,1,0,5,8,0,1,5],[9,9,6,6,1,2,4,8],[4,8,7,3,8,7,4,7],[4,6,1,9,7,0,1,7],[7,6,7,1,9,4,1,6],[8,0,0,8,5,5,9,9],[4,6,4,8,9,4,8,6],[9,0,8,7,6,2,1,5]] -> 2937504
[[1,2,3,4,5,6,7,8],[2,3,4,5,6,7,8,1],[3,4,5,6,7,8,1,2],[4,5,6,7,8,1,2,3],[5,6,7,8,1,2,3,4],[6,7,8,1,2,3,4,5],[7,8,1,2,3,4,5,6],[8,1,2,3,4,5,6,7]] -> -10549504
[[1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0],[0,1,1,1,1,0,0,1,0,1,1,1,1,1,1,0],[1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,0],[0,1,1,1,1,0,0,0,0,1,1,1,1,1,0,1],[1,0,1,0,1,1,1,0,0,1,1,1,1,0,1,0],[0,0,1,1,1,0,1,1,1,1,1,1,1,0,0,0],[1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1],[1,1,0,1,1,1,1,1,1,1,1,1,0,1,0,1],[1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1],[0,1,1,1,1,1,1,1,1,0,0,1,0,1,0,1],[1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[1,1,0,1,1,0,1,1,1,1,1,0,0,1,1,0],[1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[1,0,1,0,0,1,0,1,0,1,1,1,1,1,0,1],[1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,1]] -> -8

(이 도전에 도움을 주신 @ MartinBüttner에게 감사합니다)


3
재미있는 사실 : 이것에 대해 몇 가지 실험을 실행했으며 재귀 결정 기가 0이 아닌 놀랍게도 많은 이진 행렬이 있습니다. 크기 2x2, 4x4, 8x8, 16x16의 경우 6, 16488, 2229617029168687104, 3349795881591711813037585032680117995553655026185547430764970842694019448832 0이 아닌 행렬이있는 행렬은 각각 37.5 %, 25.1587 %, 각각 12.0868 %, 2.89294입니다.
Martin Ender

@ MartinBüttner : 6, 22560, 10160459763342013440, ... A055165 와 일치 합니다 .
Charles

@Charles odd, 내 코드를 확인하겠습니다
Martin Ender

@ MartinBüttner : 아마도 우리는 두 가지 다른 것을 계산하고 있습니까?
Charles

@Charles 매트릭스를 고려하십시오 [1,0,1,0;1,1,1,1;1,1,1,1;0,0,0,1]. 두 개의 동일한 행이 있으므로 전체 결정 요인은 0입니다. 따라서 이것은 단수 (비가 역적) 4x4 행렬이므로 A055165에 포함되지 않습니다. 그러나 여기서 논의되는 "재귀 적"결정 요인은 1*1-1*0==1입니다. 반대 방향으로, 매트릭스 [0,0,0,1;1,0,0,0;0,1,0,0;0,0,1,0]는 "재귀 적"결정자를 갖는다 0*0-0*0==0. 그러나 행은 다른 순서로 항등 행렬의 행일 뿐이므로 전체 결정 요인은 0이 아니어야합니다. 그리고 A055165에 의해 계산됩니다.
Jeppe Stig Nielsen

답변:


8

J, 21 25 바이트

0{0{(_2(_2-/ .*\|:)\])^:_

용법:

   ]input=.(3,1,4,1),(5,9,2,6),(5,3,5,8),:(9,7,9,3)
3 1 4 1
5 9 2 6
5 3 5 8
9 7 9 3
   (0{0{(_2(_2-/ .*\|:)\])^:_) input
_1430

모든 단계에서 행렬을 2x2로 자르고 각 행렬을 결정하여 다음 단계의 입력 행렬을 만듭니다. 결과가 변경되지 않을 때까지이 프로세스를 반복합니다 (최종 요소는 결정자 자체 임). 를 사용하여 최종 결과를 스칼라로 변환합니다 0{0{.

여기에서 온라인으로 사용해보십시오.


컷의 타일링 기능을 사용하여이 작업을 시도했지만 버전까지 골프를 칠 수 없었습니다. 29 바이트 : (2 2$2)&(-/ .*;._3^:(2^.#@])) 온라인으로 사용해보십시오!
Jonah

4

매스 매 티카, 52 40 바이트

12 바이트를 절약 해 준 Martin Büttner에게 감사합니다.

Tr[#//.l:{_,__}:>BlockMap[Det,l,{2,2}]]&

설명

BlockMap[f,expr,n]expr크기의 하위 목록으로 분할 하고 모든 하위 목록에 n매핑 f합니다. BlockMap[Det,#,{2,2}]&입력 배열을 2 * 2 블록으로 분할하고 결정 요인을 계산하십시오.


테스트 사례

%[{{3,1,4,1},{5,9,2,6},{5,3,5,8},{9,7,9,3}}]
(* -1430 *)

1
Sp3000과의 챌린지 아이디어를 논의하면서 Mathematica에서 참조 구현을 작성했으며 40 바이트입니다. 그래도 당신과 매우 비슷하므로 원하는 경우 직접 찾을 수있는 시간을 줄 것입니다. :)
Martin Ender

@ MartinBüttner 실패했습니다. :(
njpipeorgan

1
당신은 피할 수 [[1,1]]TrNest와를 //.:Tr[#//.l:{_,__}:>BlockMap[Det,l,{2,2}]]&
마틴 청산

@ MartinBüttner 사실, 나는 //를 생각해 냈습니다. J로 대답을 읽을 때 아이디어가 있지만 배열과 일치하는 좋은 방법을 찾아 내었습니다. : P
njpipeorgan

당신의 대답 업데이트 내 솔루션을 사용하여 주시기 바랍니다
마틴 청산

3

젤리, 20 17 바이트

s€2s2U×¥/€ḅ-µL¡SS

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 한 번에 확인하십시오 .

작동 원리

s€2s2U×¥/€ḅ-µL¡SS  Main link. Input: M (matrix)

s€2                Split each row of M into pairs.
   s2              Split the result into pairs of rows.
        /€         Reduce each pair...
       ¥             by applying the following, dyadic chain:
     U                 Reverse each pair of the left argument (1st row).
      ×                Multiply element-wise with the right argument (2nd row).
          ḅ-       Convert each resulting pair from base -1 to integer.
                   This maps [a, b] -> b - a.
            µ      Turn the previous links into a monadic chain. Begin a new one.
             L     Yield the length of the input.
              ¡    Execute the previous chain L times.
                   log2(L) times would do, but who's counting?
               SS  Sum twice to turn the resulting 1x1 matrix into a scalar.

2

하스켈 , 93 86 바이트

편집 : 전체 7 바이트를 줄인 @Laikoni에게 감사드립니다!

f[[a,b],[c,d]]=a*d-b*c
f m|let l=[take,drop]<*>[div(length m)2]=f[f.($b<$>m)<$>l|b<-l]

나는 = 전에 let 문을 넣을 수 있다는 것을 몰랐고 그 모나드 연산자에 익숙해지지 않았습니다. 다시 감사합니다 @Laikoni

구 버전:

f[[a,b],[c,d]]=a*d-b*c
f m=f[[f$a$map b m|a<-l]|b<-l]where h=length m`div`2;l=[take h,drop h]

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

이것은 두 가지 다른 방식으로 반복되는 기능입니다. 먼저 패턴 일치는 기본 사례 인 2x2 행렬을 포착하고 계산을 수행합니다. 나는 이것을 사용하여 재귀 적 솔루션이있는 2x2 행렬로 함수를 호출하여 재귀 적 사례에서 계산을 수행합니다. 이 행렬은 각각 목록을 반으로 자르는 함수 배열을 두 번 반복하여 생성됩니다. 간단한 호출로 행에 적용하고을 사용하여 열에 적용합니다 map.


대신을 where h=length m`div`2;l=[take h,drop h]사용할 수 있습니다 f m|let l=[take,drop]<*>[length m`div`2]=. map b m될 수있는 b<$>m[f$a$b<$>m|a<-l]더 단축 될 수있다 f.($b<$>m)<$>l. 모두 86 바이트 : [ tio.run/… 온라인으로 사용해보십시오!]
Laikoni

1

파이썬, 166 바이트

def f(m):l=len(m)/2;g=lambda x,y:[(s[:l],s[l:])[x]for s in(m[:l],m[l:])[y]];return f(g(0,0))*f(g(1,1))-f(g(0,1))*f(g(1,0)) if l>1 else m[0][0]*m[1][1]-m[1][0]*m[0][1]

제공된 모든 테스트 사례를 통과합니다. m은 (테스트 사례에서와 같이) 2D 배열이어야하고, g는 하위 행렬을 선택합니다.


1

피스, 26

M-F*VG_HhhumgMCcR2dcG2llQQ

테스트 스위트

여기에는 두 부분이 있습니다. M-F*VG_H2x2 g행렬의 행렬식을 계산하기 위해 함수 를 재정의합니다 . 두 행의 압축을 풀기 때문에 한 번만 사용하더라도 바이트가 절약됩니다.

다른 부분은 우리가 호출하는 큰 Reduce 문입니다 log_2( len( input() ) ). 불행히도 1 x 1 행렬에서 축소 단계를 수행하면 결과가 목록에 래핑되므로 고정 소수점을 얻지 못합니다. 감소는 대부분 행렬을 2x2 행렬로 나누고 적용하는 것 g입니다.


1

MATL , 26 30 바이트

`tnX^teHHhZC2Ih2#Y)pwp-tnq

입력은로 구분 된 행이있는 2D 배열 ;입니다.

[3 1 4 1; 5 9 2 6; 5 3 5 8; 9 7 9 3]

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

`             % do...while loop
  tnX^te      %   reshape into square matrix. Implicitly asks for input the first time
  HHhZC       %   transform each 2x2 block into a column
  2Ih2#Y)     %   push matrix with rows 2,3, and also matrix with remaining rows (1,4)
  pwp-        %   multiplications and subtraction to compute the 2x2 determinants
  tnq         %   condition of do...while loop: is number of elements greater than 1?
              % implicitly end loop
              % implicitly display

1

Perl 5 , 120 + 1 ( -a) = 121 바이트

while($#F){@r=();for$i(@o=0..($l=sqrt@F)/2-1){push@r,$F[$k=$i*$l*2+2*$_]*$F[$k+$l+1]-$F[$k+$l]*$F[$k+1]for@o}@F=@r}say@F

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

공백으로 구분 된 숫자 목록으로 입력을받습니다.


0

ES6, 91 바이트

(a,x=0,y=0,w=a.length)=>(w>>=1)?f(a,x,y,w)*f(a,x+w,y+w,w)-f(a,x,y+w,w)*f(a,x+w,y,w):a[x][y]

간단한 재귀 솔루션.



0

Groovy, 221 189 바이트 (현재 Java를 사용할 수 있음)

f={x->b=x.size();c=b/2-1;a=(0..c).collect{i->(0..c).collect{j->z=x.toList().subList(i*2,i*2+2).collect{it.toList().subList(j*2,j*2+2)};z[0][0]*z[1][1]-z[0][1]*z[1][0];}};a.size()==1?a:f(a)}

Java (221 바이트) 일 수도있는 오래된 크 래피 버전 :

f={x->b=x.size();a=new int[b/2][b/2];for(i=0;i<b-1;i+=2){for(j=0;j<b-1;j+=2){z=x.toList().subList(i,i+2).collect{it.toList().subList(j,j+2)};a[(int)(i/2)][(int)(j/2)]=z[0][0]*z[1][1]-z[0][1]*z[1][0];}};a.size()==1?a:f(a)}

Ungolfed 코드 :

f=
{x->
  b=x.size();
  int[][]a=new int[b/2][b/2];
  for(i=0;i<b-1;i+=2) {
    for(j=0;j<b-1;j+=2) {
      z=x.toList().subList(i,i+2).collect{
        it.toList().subList(j,j+2)
      };
      a[(int)(i/2)][(int)(j/2)]=z[0][0]*z[1][1]-z[0][1]*z[1][0];
    }
  }
  a.size()==1
    ?
      a:f(a)
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.