บล็อกขวางค่าใช้จ่ายขั้นต่ำ


10

พิจารณาเมทริกซ์บล็อกแนวขวางแบบไบบล็อกซึ่งมีบล็อกสี่เหลี่ยมจัตุรัส 1s บนเส้นทแยงมุมหลักและเป็น 0 ทุกที่ ลองเรียกเมทริกซ์นั้นว่า "ถูกต้อง"

ตัวอย่างเช่นต่อไปนี้เป็นเมทริกซ์ 4x4 ที่ถูกต้อง:

1 0 0 0     1 1 0 0     1 0 0 0     1 0 0 0     1 1 0 0    1 1 1 1
0 1 0 0     1 1 0 0     0 1 1 0     0 1 1 1     1 1 0 0    1 1 1 1
0 0 1 0     0 0 1 0     0 1 1 0     0 1 1 1     0 0 1 1    1 1 1 1
0 0 0 1     0 0 0 1     0 0 0 1     0 1 1 1     0 0 1 1    1 1 1 1

โปรดทราบว่าอีกวิธีหนึ่งในการอธิบายเมทริกซ์นั้นคือมีห่วงโซ่ของสี่เหลี่ยมจัตุรัส 1 ช่วงตึกจากด้านบนซ้ายไปยังด้านล่างขวาล่างแตะมุมจากมุมหนึ่งไปอีกมุมหนึ่งและอีกที่หนึ่งคือ 0

สำหรับความคมชัดนี่คือเมทริกซ์ 4x4 ที่ไม่ถูกต้องบางส่วน:

1 0 1 0     1 0 1 0     1 1 0 0     0 1 1 1     1 1 0 0    0 0 0 0
0 1 1 1     0 1 0 1     1 1 0 0     0 1 1 1     1 1 0 0    0 0 0 0
1 0 0 1     1 0 1 0     0 0 0 0     0 1 1 1     1 1 0 0    0 0 0 0
0 0 1 0     0 1 0 1     0 0 0 1     1 0 0 0     0 0 1 1    0 0 0 0

คุณจะได้รับnโดยnเมทริกซ์ไบนารีเป็นอินพุท - จำนวน0บิตขั้นต่ำที่คุณต้องตั้งค่า1เพื่อรับเมทริกซ์ที่ถูกต้องคืออะไร?

คุณอาจจะเขียนฟังก์ชั่นหรือโปรแกรมการในสะดวกสตริงรายการหรือเมทริกซ์รูปแบบใด ๆ ที่เป็นตัวแทนnจากnเมทริกซ์ของ 0s และ 1s (ตราบใดที่มันไม่ได้ประมวลผลล่วงหน้า) แถวจะต้องแยกอย่างชัดเจนในบางวิธีดังนั้นรูปแบบเช่นบิต 1D ของอาร์เรย์จะไม่ได้รับอนุญาต

นี่คือดังนั้นเป้าหมายคือเพื่อลดจำนวนไบต์ในโปรแกรมของคุณ

ตัวอย่าง

ตัวอย่างเช่นถ้าอินพุตเป็น

0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 1

ดังนั้นคำตอบคือ 5 เนื่องจากคุณสามารถตั้งค่าห้า0บิตเป็น1:

1 0 0 0 0
0 1 1 0 0
0 1 1 0 0
0 0 0 1 0
0 0 0 0 1

และนี่คือจำนวนขั้นต่ำที่ต้องการ อย่างไรก็ตามหากอินพุตถูก

0 0 0 0 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

ดังนั้นคำตอบคือ 24 เนื่องจากเมทริกซ์ 5x5 ที่ถูกต้องเพียงตำแหน่งเดียวที่มุมบนขวาคือ1เมทริกซ์ของ1s ทั้งหมด

กรณีทดสอบ

การทดสอบจะแสดงที่นี่เป็นอาร์เรย์ของจำนวนเต็ม 2 มิติ

[[0]] -> 1
[[1]] -> 0
[[0,1],[0,0]] -> 3
[[1,0],[0,0]] -> 1
[[0,0,0],[0,1,0],[0,0,0]] -> 2
[[0,1,0],[0,0,0],[0,1,0]] -> 7
[[0,1,0],[1,0,0],[0,0,1]] -> 2
[[1,1,1],[1,1,1],[1,1,1]] -> 0
[[0,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,0]] -> 4
[[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,0,0,1]] -> 8
[[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,0,1,0]] -> 14
[[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,1,0,0]] -> 14
[[0,0,0,0,0],[0,0,0,0,0],[0,1,0,0,0],[0,0,0,0,1],[0,0,0,0,0]] -> 7
[[0,0,0,0,0],[0,0,0,0,0],[1,0,0,0,0],[0,0,0,0,1],[0,0,0,0,0]] -> 11
[[0,0,0,0,0],[0,0,1,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,1]] -> 5
[[0,0,0,0,1],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]] -> 24
[[0,0,0,1,0],[0,0,0,0,1],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]] -> 23
[[0,1,0,0,0],[1,0,0,0,0],[0,0,1,0,0],[0,0,0,0,1],[0,0,0,1,0]] -> 4
[[0,1,1,1,0],[0,1,1,0,1],[0,1,1,1,0],[0,1,0,0,1],[0,0,0,0,0]] -> 14

หมายเหตุ

คำตอบ:


3

MATL , 46 43 ไบต์

nX^tQt:qZ^!tsb=Z)"@!"@1$l]@n$YdG-Q?6MG>zvX<

อินพุตเป็นอาร์เรย์ 2D ที่มีเครื่องหมายอัฒภาคเป็นตัวคั่นแถว ตัวอย่างเช่นอินพุตสำหรับกรณีทดสอบสุดท้ายคือ

[0,1,1,1,0;0,1,1,0,1;0,1,1,1,0;0,1,0,0,1;0,0,0,0,0]

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด (รหัสแก้ไขเล็กน้อยเพื่อรับอินพุตทั้งหมดผลลัพธ์จะปรากฏหลังจากนั้นสองสามวินาที)

คำอธิบาย

ให้การป้อนข้อมูลที่เป็นN × Nเมทริกซ์ รหัสจะคำนวณขนาดบล็อกทั้งหมด ( N +1) ทั้งหมดที่สร้างขนาดเมทริกซ์ที่เหมาะสม ตัวอย่างเช่นสำหรับN = 4 tuples มี0 0 0 0 4, 0 0 0 1 3, ... 4 0 0 0 0, สำหรับแต่ละ tuple มันจะสร้างเมทริกซ์ขวางของบล็อกด้วยขนาดบล็อกเหล่านั้น จากนั้นตรวจสอบว่าเมทริกซ์ครอบคลุม1รายการทั้งหมดในอินพุตหรือไม่และถ้าเป็นเช่นนั้นให้จดบันทึกจำนวน1รายการที่ไม่ปรากฏในอินพุต ผลลัพธ์สุดท้ายคือจำนวนขั้นต่ำของตัวเลขที่ได้รับทั้งหมด

nX^      % Implicit input  an N×N matrix. Get N
t        % Duplicate N
Qt:q     % Vector [0 1 ... N]
Z^       % Cartesian power. Gives 2D array
!ts      % Transpose, duplicate, sum of each column
b=       % Logical vector that equals true if the sum is N
Z)       % Filter columns according to that. Only keep columns that sum to N. Each 
         % column is the size of one block
"        % For each column
  @      %   Push that column
  "      %   For each entry of that column
    @    %     Push that entry
    1$l  %     Square matrix with that size, filled with 1
  ]      %   End
  @n     %   Column size. This is the number of blocks in the block-diagonal matrix
  $Yd    %   Build block-diagonal matrix from those blocks
  G-Q    %   Subtract input matrix element-wise, and add 1
  ?      %   If all entries are nonzero (this means each that entry that is 1 in the
         %   block-diagonal matrix is also 1 in the input matrix)
    6M   %   Push block-diagonal matrix again
    G>   %   For each entry, gives 1 if it exceeds the corresponding entry of the
         %   input, that is, if the block-diagonal matrix is 1 and the input is 0
    z    %   Number of 1 entries
    v    %   Concatenate vertically with previous values
    X<   %   Take minimum so far
         %   Implicit end
         % Implicit end
         % Implicit display

3

Python กับ numpy, 102

from numpy import*
lambda M:sum(diff([k for k in range(len(M)+1)if(M|M.T)[:k,k:].any()-1])**2)-M.sum()

อัลกอริทึมที่มีประสิทธิภาพ ค้นหา "จุดคอ" ในแนวทแยงมุมที่สามารถแยกบล็อก สิ่งเหล่านี้มี 0 ทั้งหมดข้างบนและขวาเช่นเดียวกับด้านล่างและซ้าย บล็อกน้อยที่สุดคือระหว่างจุดคอ

??000
??000
00???
00???
00???

ความยาวของบล็อกคือความแตกต่างระหว่างจุดคอต่อเนื่องดังนั้นพื้นที่ทั้งหมดของพวกเขาคือผลรวมของกำลังสองของ การลบผลรวมของเมทริกซ์ดั้งเดิมจากนั้นให้จำนวนการพลิกที่ต้องการจาก 0 ถึง 1


2

Pyth, 45 ไบต์

-hSlMf@I.DRlQx1sQTms.b^+LsYN2d+0._ds.pM./lQss

งานที่ยากดังนั้นมันค่อนข้างยาว

ลองใช้ออนไลน์: การสาธิตหรือชุดทดสอบ

คำอธิบาย:

s.pM./lQlen(matrix)คำนวณพาร์ทิชันจำนวนเต็มทั้งหมดของ ms.b^+LsYN2d+0._dแปลงให้เป็นพิกัดคู่ ยกตัวอย่างเช่นพาร์ติชัน[1, 2, 2]ของได้รับในแปลง5[[0,0], [1,1], [1,2], [2,1], [2,2], [3,3], [3,4], [4,3], [4,4]

f@I.DRlQx1sQTจากนั้นฟิลเตอร์สำหรับพาร์ติชั่นที่ซ้อนทับเมทริกซ์ ( .DRlQx1sQคำนวณพิกัดคู่ทั้งหมดของเซลล์ที่ใช้งานในเมทริกซ์)

-hSlM...ss นับเซลล์ของแต่ละพาร์ติชันที่เหลืออยู่เลือกเซลล์ที่มีเซลล์น้อยที่สุดและลบเซลล์ที่ใช้งานอยู่แล้ว


0

Matricks , 180 ไบต์ (ไม่ใช่การแข่งขัน)

Matricks เป็น esolang ใหม่ที่ฉันสร้างขึ้นเมื่อเร็ว ๆ นี้เพื่อจัดการกับปัญหาเมทริกซ์ (เช่นอันนี้) โดยมีเพียง 2 ชนิดข้อมูล: ลอยและ matricies ยังไม่ได้เป็นคุณลักษณะที่สมบูรณ์และยังคงมีการดำเนินการที่ขาดหายไปจำนวนมาก (ฉันต้องเพิ่มฟังก์ชันการทำงานบางอย่างสำหรับความท้าทายนี้) อย่างไรก็ตามนี่คือรหัส:

il=1:j3;:bdx;;;s1::L;j1;;
b{q:1;mgr:c;|gc:r;|(r=c)|(gr-1:c;|gr:c+1;)&(rec)|(gr+1:c;|gr:c-1;)&(cer):l:L;};z:(l-1)/2;B1;s1::g1:;-1;ig1:;=0:j2;:j1;;
s1::d{q:1;};;kg1:;-g:;;
kg:;*-1+1;

คำอธิบาย

ส่วนแรกil=1:j3;:...;ตรวจสอบว่าอาร์เรย์มีขนาด 1 หรือไม่ถ้าใช่จะข้ามไปที่บรรทัดสุดท้ายkg:;*-1+1;ซึ่งเป็น0 <-> 1ฟังก์ชันแบบง่าย

มิฉะนั้นจะดำเนินการต่อในส่วนที่เหลือของรหัส bdx;;;ตั้งค่าเซลล์0,0เป็นผลรวมปัจจุบันและs1::L;j1;สร้างตัวนับในเซลล์ในแถวด้านล่าง

บรรทัดถัดไปซับซ้อนกว่าเล็กน้อย มันคือลูปที่รันnครั้งnเป็นขนาดของเมทริกซ์ ฉันจะใช้กรณีทดสอบครั้งที่ 3 เป็นตัวอย่าง เมื่อเราไปถึงบรรทัดแรกเมทริกซ์จะเป็นดังนี้:

1 0 1
2 0 0

{q:1;m...;}ครั้งแรกที่เราไปสู่ความเข้าใจเมทริกซ์ สิ่งนี้ทำให้เส้นทแยงมุมและพยายามทำให้ดีที่สุดในการล้าง 0 ที่จำเป็นต้องกรอกข้อมูลทั้งหมดนี้ทำได้โดยใช้ตัวดำเนินการบูลีนแบบง่าย จากนั้นเราเติมมันลงในเมทริกซ์ปัจจุบันโดยให้สิ่งนี้:

    V--data we want to keep
1 1 1 0 1 <-|
1 1 2 0 0 <-- old matrix

จากนั้นเราตัดของเมทริกซ์เก่าใช้และหมุนเมทริกซ์ทั้งหมดไปทางซ้ายใช้z:(l-1)/2; B1;นั่นทำให้เมทริกซ์ของเราพร้อมสำหรับการทำซ้ำครั้งถัดไปโดยมีลักษณะดังนี้:

1 1 1
2 1 1

ในที่สุดเราลดจำนวนตัวตรวจสอบและดำเนินการต่อ ig1:;=0:j2;:j1;;

s1::d{q:1;};;เมื่อวงเสียจากเราจะพบผลรวมใหม่และตั้งจุดเคาน์เตอร์เก่าที่มี kg1:;-g:;;สุดท้ายเราจะใช้ความแตกต่างและกลับ kตั้งค่าอาร์เรย์ปัจจุบันเป็นค่าและการพิมพ์มีความหมายโดยนัย

...

อย่างที่คุณเห็นMatricksนั้นค่อนข้างละเอียดและไม่ใช่ภาษากอล์ฟที่ดีนัก แต่ห่าฉันอยากจะแสดงมันออกมา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.