ตัวกำหนด 2x2 แบบเรียกซ้ำ


17

ดีเทอร์มีแนนต์ของเมทริกซ์ 2 คูณ 2

a b
c d

ad - bcจะได้รับจาก

ด้วยเมทริกซ์ของตัวเลขที่มีขนาด 2 nคูณ 2 n , n ≥ 1 ส่งออกผลลัพธ์ที่ได้จากการคำนวณดีเทอร์มิแนนต์ของแต่ละบล็อกย่อย 2 คูณ 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
  • คุณสามารถรับข้อมูลในรูปแบบรายการหรือรูปแบบสตริงใด ๆ ก็ได้ตราบใดที่ยังไม่มีการประมวลผลข้อมูลล่วงหน้า เนื่องจากเมทริกซ์นั้นเป็นรูปสี่เหลี่ยมเสมอคุณอาจรับอินพุตเป็นรายการ 1D เดียวแทนรายการ 2D หากคุณต้องการ
  • อินพุตสามารถผ่านฟังก์ชั่นอินพุต, 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
ความจริงแล้วสนุก: ฉันทำการทดลองเกี่ยวกับเรื่องนี้และมีเมทริกซ์ไบนารีจำนวนมากอย่างน่าประหลาดใจที่มีตัวกำหนดแบบเรียกซ้ำไม่เป็นศูนย์ สำหรับขนาด 2x2, 4x4, 8x8, 16x16 เราจะได้ 6, 16488, 2229617029168687104, 3349795881591711813037585032680117995553655026185547430764970842694019448323 สำหรับขนาด 2x2, 4x4, 8x8, 16x16 เราจะได้รับ 6, 16488, 2229617029168687104, 33497958815917118130975113
Martin Ender

@ MartinBüttner: ผมได้รับ 6, 22560, 10160459763342013440 ... ซึ่งตรงA055165
ชาร์ลส์

@ Charles แปลกฉันจะตรวจสอบรหัสของฉัน
Martin Ender

@ MartinBüttner: เป็นไปได้ว่าเรากำลังคำนวณสองสิ่งที่แตกต่างกันหรือไม่?
ชาร์ลส์

@Charles [1,0,1,0;1,1,1,1;1,1,1,1;0,0,0,1]พิจารณาเมทริกซ์ ดีเทอร์มีแนนต์เต็มของมันคือศูนย์เนื่องจากมันมีสองแถวเหมือนกัน อันนี้จึงเป็นเอกพจน์ (หมายถึงไม่กลับหัว) เมทริกซ์ 4 × 4 ดังนั้นจึงไม่นับ A055165 อย่างไรก็ตาม "recursive" 1*1-1*0==1ปัจจัยที่กล่าวถึงที่นี่เป็น ในทิศทางที่ตรงข้ามเมทริกซ์[0,0,0,1;1,0,0,0;0,1,0,0;0,0,1,0]มี "recursive" 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

ในทุกขั้นตอนเราตัดเมทริกซ์เป็น 2 คูณ 2 และคำนวณหาดีเทอร์มิแนนต์แต่ละตัวทำให้เกิดเมทริกซ์อินพุทขั้นต่อไป เราทำซ้ำขั้นตอนนี้จนกว่าผลลัพธ์จะไม่เปลี่ยนแปลง (องค์ประกอบสุดท้ายคือตัวกำหนดเอง) 0{0{เราแปลงผลสุดท้ายจะเกลาด้วย

ลองออนไลน์ได้ที่นี่


ลองใช้ฟังก์ชั่นเรียงต่อกันของ Cut เพื่อทำสิ่งนี้ แต่ไม่สามารถตีได้ไกลเท่ากับเวอร์ชั่นของคุณ 29 ไบต์: (2 2$2)&(-/ .*;._3^:(2^.#@])) ลองออนไลน์!
Jonah

4

มาติกา 52 40 ไบต์

ขอบคุณ Martin Büttnerที่ช่วยประหยัด 12 ไบต์

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
ฉันเขียนการใช้งานอ้างอิงใน Mathematica ขณะที่พูดคุยแนวคิดท้าทายกับ Sp3000 และมีขนาด 40 ไบต์ มันค่อนข้างคล้ายกับของคุณดังนั้นฉันจะให้เวลาคุณในการค้นหาด้วยตัวคุณเองถ้าคุณชอบ :)
Martin Ender

@ MartinBüttnerฉันล้มเหลว :(
njpipeorgan

1
คุณสามารถหลีกเลี่ยง[[1,1]]ด้วยTrและNestด้วย//.:Tr[#//.l:{_,__}:>BlockMap[Det,l,{2,2}]]&
Martin Ender

@ MartinBüttnerอันที่จริงฉันมาด้วย // แนวคิดเมื่ออ่านคำตอบใน J แต่ติดอยู่ในการหาวิธีที่ดีในการจับคู่อาร์เรย์ : P
njpipeorgan

อย่าลังเลที่จะใช้โซลูชันของฉันเพื่ออัปเดตคำตอบของคุณ
Martin Ender

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

Haskell , 93 86 ไบต์

แก้ไข: ขอบคุณ @Laikoni ที่ย่อขนาดทั้ง 7 ไบต์ให้สั้นลง!

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 ก่อนหน้า = และฉันไม่เคยชินกับผู้ประกอบการ monad เหล่านั้น ขอบคุณอีกครั้ง @Likikoni

เวอร์ชั่นเก่า:

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] สามารถและสามารถตัดให้สั้นลงไปอีก ทั้งหมด 86 ไบต์: [ tio.run/…ลองออนไลน์!]f m|let l=[take,drop]<*>[length m`div`2]=map b mb<$>m[f$a$b<$>m|a<-l]f.($b<$>m)<$>l
Laikoni

1

Python ขนาด 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 ต้องเป็นอาร์เรย์ 2 มิติ (เช่นในกรณีทดสอบ), g จะเลือกเมทริกซ์ย่อย


1

Pyth, 26

M-F*VG_HhhumgMCcR2dcG2llQQ

ชุดทดสอบ

นี่มีสองส่วน: M-F*VG_Hกำหนดฟังก์ชันใหม่gเพื่อคำนวณดีเทอร์มีแนนต์ของเมทริกซ์สองคูณสอง สิ่งนี้จะช่วยประหยัดไบต์แม้ว่าเราจะใช้เพียงครั้งเดียวเพราะมันคลายสองแถว

อีกส่วนหนึ่งเป็นคำสั่งลดขนาดใหญ่ที่เราเรียกlog_2( len( input() ) )เวลา น่าเสียดายที่การทำขั้นตอนหนึ่งในการลดเมทริกซ์แบบ 1 ต่อ 1 ทำให้ผลลัพธ์ถูกห่อในรายการดังนั้นเราจึงไม่ได้รับจุดคงที่ ลดส่วนใหญ่จะเป็นเพียงแค่แยกเมทริกซ์ที่จะได้รับ 2 2 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)}

รหัสไม่ได้รับการตอบกลับ:

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.