Đệ quy quyết định 2x2


17

Yếu tố quyết định của ma trận 2 by 2

a b
c d

được đưa ra bởi ad - bc.

Cho ma trận các chữ số có kích thước 2 n x 2 n , n ≥ 1, xuất kết quả thu được bằng cách tính toán đệ quy định thức của mỗi khối 2 cho 2 khối phụ cho đến khi chúng ta đạt được một số duy nhất.

Ví dụ, đưa ra đầu vào

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

Sau một bước, chúng tôi có được:

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

Và lặp lại một lần nữa, chúng ta nhận được:

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

Do đó, đầu ra nên được -1430.

Quy tắc

  • Các phần tử của ma trận sẽ luôn là các số nguyên một chữ số, tức là 0 đến 9.
  • Bạn có thể nhận đầu vào ở bất kỳ định dạng chuỗi hoặc danh sách thuận tiện, miễn là không xử lý trước dữ liệu. Vì ma trận luôn vuông, bạn có thể lấy đầu vào dưới dạng danh sách 1D thay vì danh sách 2D nếu muốn.
  • Đầu vào có thể thông qua đầu vào chức năng, STDIN, đối số dòng lệnh hoặc thay thế gần nhất.
  • Đầu ra phải là một số nguyên duy nhất cho đầu ra chức năng, STDOUT hoặc thay thế gần nhất. Bạn không thể xuất số nguyên duy nhất trong danh sách hoặc ma trận.
  • Bạn có thể sử dụng các phương thức thao tác xác định và ma trận dựng sẵn nếu ngôn ngữ của bạn xảy ra để hỗ trợ chúng.
  • Thuật toán của bạn phải hoạt động trên lý thuyết cho bất kỳ đầu vào hợp lệ.
  • Luật tiêu chuẩn được áp dụng.

Các trường hợp thử nghiệm

Các trường hợp thử nghiệm sau đây được đưa ra dưới dạng danh sách kiểu 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

(Cảm ơn @ MartinBüttner đã giúp đỡ với thử thách này)


3
Sự thật thú vị: Tôi đã thực hiện một số thí nghiệm về điều này và có một số lượng lớn ma trận nhị phân lớn đáng ngạc nhiên với định thức đệ quy khác không. Đối với các kích thước 2x2, 4 x 4, 8 x 8, 16 x 16, chúng tôi nhận được 6, 16488, 2229617029168687104, 33497958815917118130375850326801179955536550261855474307650326801179955536550261855474307650708
Martin Ender

@ MartinBüttner: Tôi nhận được 6, 22560, 10160459763342013440, ... phù hợp với A055165 .
Charles

@Charles lẻ, tôi sẽ kiểm tra mã của mình
Martin Ender

@ MartinBüttner: Có thể chúng ta chỉ đang tính toán hai thứ khác nhau?
Charles

@Charles Hãy xem xét ma trận [1,0,1,0;1,1,1,1;1,1,1,1;0,0,0,1]. Yếu tố quyết định đầy đủ của nó bằng không vì nó có hai hàng giống nhau. Do đó, đây là ma trận 4 × 4 số ít (có nghĩa là không thể đảo ngược), do đó, nó không được tính bằng A055165. Tuy nhiên, yếu tố quyết định "đệ quy" được thảo luận ở đây là 1*1-1*0==1. Theo hướng ngược lại, ma trận [0,0,0,1;1,0,0,0;0,1,0,0;0,0,1,0]có định thức "đệ quy" 0*0-0*0==0. Tuy nhiên, định thức đầy đủ của nó phải khác không vì các hàng của nó chỉ là các hàng của ma trận danh tính theo thứ tự khác; và nó được tính bằng A055165.
Jeppe Stig Nielsen

Câu trả lời:


8

J, 21 25 byte

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

Sử dụng:

   ]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

Ở mỗi bước, chúng tôi cắt ma trận thành 2 nhân 2 và tính toán từng yếu tố quyết định dẫn đến ma trận đầu vào của bước tiếp theo. Chúng tôi lặp lại quá trình này cho đến khi kết quả không thay đổi (yếu tố cuối cùng là yếu tố quyết định). Chúng tôi chuyển đổi kết quả cuối cùng thành vô hướng với 0{0{.

Hãy thử trực tuyến tại đây.


Đã thử sử dụng chức năng ốp lát của Cut để làm điều này, nhưng không thể chơi nó xa như phiên bản của bạn. 29 byte: (2 2$2)&(-/ .*;._3^:(2^.#@])) Hãy thử trực tuyến!
Giô-na

4

Toán học, 52 40 byte

Cảm ơn Martin Büttner đã lưu 12 byte.

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

Giải trình

BlockMap[f,expr,n]chia exprthành các danh sách con về kích thước nvà bản đồf trên mỗi danh sách phụ. BlockMap[Det,#,{2,2}]&chia mảng đầu vào thành các khối 2 * 2 và tính toán các yếu tố quyết định của chúng.


Trường hợp thử nghiệm

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

1
Tôi đã viết một triển khai tham chiếu trong Mathicala trong khi thảo luận về ý tưởng thử thách với Sp3000 và nó là 40 byte. Mặc dù nó khá giống với bạn, vì vậy tôi sẽ cho bạn một chút thời gian để tự tìm nó nếu bạn thích. :)
Martin Ender

@ MartinBüttner Tôi thất bại. :(
njpipe tổ chức

1
Bạn có thể tránh [[1,1]]với TrNestvới //.:Tr[#//.l:{_,__}:>BlockMap[Det,l,{2,2}]]&
Martin Ender

@ MartinBüttner Thật ra, tôi đã nghĩ ra //. ý tưởng khi đọc câu trả lời trong J, nhưng bị mắc kẹt trong việc tìm ra một cách tốt để phù hợp với mảng. : P
njpipe tổ chức

vui lòng sử dụng giải pháp của tôi để cập nhật câu trả lời của bạn
Martin Ender

3

Thạch, 20 17 byte

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

Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm cùng một lúc .

Làm thế nào nó hoạt động

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

Haskell , 93 86 byte

EDIT: Cảm ơn @Laikoni vì đã rút ngắn toàn bộ 7 byte này!

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]

Tôi không biết bạn có thể đặt câu lệnh let trước = và tôi chưa bao giờ quen với các toán tử đơn nguyên đó. Cảm ơn một lần nữa @Laikoni

Phiên bản cũ:

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]

Hãy thử trực tuyến!

Đây là một chức năng tự lặp lại theo hai cách khác nhau. Đầu tiên, khớp mẫu bắt được trường hợp cơ sở: ma trận 2x2 và nó thực hiện phép tính. Tôi sử dụng điều này để thực hiện phép tính trong trường hợp đệ quy bằng cách gọi hàm với ma trận 2x2 mà tôi tạo có các giải pháp đệ quy trong đó. Ma trận đó được tạo ra bằng cách lặp hai lần trên một mảng các hàm mà mỗi hàm chia một nửa danh sách. Tôi áp dụng nó cho các hàng với một cuộc gọi đơn giản và áp dụng nó cho các cột bằng cách sử dụng map.


Thay vì where h=length m`div`2;l=[take h,drop h], bạn có thể sử dụng f m|let l=[take,drop]<*>[length m`div`2]=. map b mcó thể b<$>m, và [f$a$b<$>m|a<-l]có thể được rút ngắn hơn nữa f.($b<$>m)<$>l. Tổng cộng 86 byte: [ tio.run/ Từ Hãy thử trực tuyến!]
Laikoni

1

Python, 166 byte

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]

Điều này vượt qua tất cả các trường hợp thử nghiệm được cung cấp. m phải là một mảng 2D (như trong các trường hợp thử nghiệm), g chọn ma trận con.


1

Bình thường, 26

M-F*VG_HhhumgMCcR2dcG2llQQ

Phòng thử nghiệm

Điều này có hai phần: M-F*VG_Hxác định lại hàm gđể tính định thức của ma trận hai bằng hai. Điều này tiết kiệm byte mặc dù chúng tôi chỉ sử dụng một lần vì nó giải nén hai hàng.

Phần khác là một tuyên bố giảm lớn mà chúng ta gọi là log_2( len( input() ) )thời gian. Thật không may, thực hiện một bước trong việc giảm ma trận 1 trên 1 khiến kết quả được gói trong một danh sách, vì vậy chúng tôi không nhận được điểm cố định. Việc giảm phần lớn chỉ là tách ma trận để có được 2 ma trận và sau đó áp dụng g.


1

MATL , 26 30 byte

`tnX^teHHhZC2Ih2#Y)pwp-tnq

Đầu vào là một mảng 2D với các hàng được phân tách bằng ;, nghĩa là

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

Hãy thử trực tuyến!

`             % 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 byte

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

Hãy thử trực tuyến!

Lấy đầu vào là một danh sách các số được phân tách bằng dấu cách.


0

ES6, 91 byte

(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]

Giải pháp đệ quy đơn giản.


0

R , 111 byte

f=function(m)"if"((n=nrow(m))-2,f(matrix(c(f(m[x<-1:(n/2),x]),f(m[y<-x+n/2,x]),f(m[x,y]),f(m[y,y])),2)),det(m))

Hãy thử trực tuyến!

Lấy đầu vào dưới dạng ma trận R (được chuyển đổi bởi hàm trong tiêu đề).


0

Groovy, 221 189 byte (Tại thời điểm này, có thể đã sử dụng 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)}

Phiên bản crappy cũ, cũng có thể là Java (221 byte):

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)}

Mã bị đánh cắp:

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)
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.