ฝาครอบสี่เหลี่ยมผืนผ้าขั้นต่ำ


23

สี่เหลี่ยมผืนผ้าครอบคลุม

สมมติว่าคุณมีเมทริกซ์ของบิตตัวอย่างเช่นต่อไปนี้

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

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

+----+         +----+
|1  1| 0  0  0 |1  1| 0
|    |         |    |
|  +-|-----+   |    |+-+
|1 |1| 1  1| 0 |1  1||1|
+----+     |   |    || |
   |       |   |    || |
 0 |1  1  1| 0 |1  1||1|
   +-------+   |    |+-+
+----+   +-----|-+  |
|1  1| 0 |1  1 |1| 1| 0
|    |   |     +----+
|    |   |       |   +-+
|1  1| 0 |1  1  1| 0 |1|
+----+   +-------+   +-+

จำนวนสี่เหลี่ยมในปกนี้คือ 7

งาน

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

จำนวนไบต์ต่ำสุดชนะ ใช้กฎมาตรฐานของ

กรณีทดสอบ

[[1]] -> 1
[[1,1]] -> 1
[[1],[1]] -> 1
[[1,0,1]] -> 2
[[1,0],[0,0]] -> 1
[[1,0],[0,1]] -> 2
[[1,0],[1,1]] -> 2
[[1,1,1],[1,0,1]] -> 3
[[0,1,0],[1,1,1],[0,1,0]] -> 2
[[1,1,1],[1,0,1],[1,1,1]] -> 4
[[1,1,0],[1,1,1],[0,1,1]] -> 2
[[1,0,1,0],[1,1,1,1],[1,0,1,0]] -> 3
[[1,1,1,0],[1,0,1,0],[1,1,1,1],[0,0,1,0]] -> 4
[[1,1,1,0],[1,0,1,0],[1,1,1,1],[0,0,1,1]] -> 5
[[1,1,1,0],[1,0,1,0],[1,1,1,1],[0,1,1,1]] -> 4
[[1,1,0,0],[1,1,1,0],[0,1,1,1],[0,0,1,1]] -> 3
[[0,1,0,0],[0,1,1,1],[1,1,1,0],[0,0,1,0]] -> 4
[[0,0,1,0,0],[0,1,1,1,0],[1,1,1,1,1],[0,1,1,1,0],[0,0,1,0,0]] -> 3

นี่เป็นแรงบันดาลใจจากแผนที่ Karnaughหรือไม่?

1
@ThePirateBay เพิ่มเติมของความซับซ้อนของการสื่อสาร nondeterministic
Zgarb

@ThePirateBay สำหรับ k-map สี่เหลี่ยมทั้งหมดควรมีขนาด power-of-two
Sparr

@Sparr ใช่ฉันรู้. ฉันเพิ่งถามว่ามันอาจเป็นแรงบันดาลใจสำหรับความท้าทายนี้

1
กรณีทดสอบที่มีประโยชน์สำหรับวิธีโลภ: [[0,1,0,0],[0,1,1,1],[1,1,1,0],[0,0,1,0]], 4
isaacg

คำตอบ:


6

Python 2 , 318 315 271 ไบต์

Mr.Xcoder, ovs และ Jonathan Frech บันทึกข้อมูลได้มากมาย

p=range
def f(x,i=0,j=-1):z=len(x[0]);j+=1;i+=j/z;j%=z;return i<len(x)and(x[i][j]and-~min([f([[v,v[:j]+[2]*(r-j)+v[r:]][i<=y<=e]for y,v in enumerate(x)],i,j)for e in p(i,len(x))for r in p(j+1,z+1)if all(all(k[j:r])for k in x[i:e+1])]+[f(x,i,j)-1]*(x[i][j]>1))or f(x,i,j))

ลองออนไลน์!


4

เยลลี่ ,  25  24 ไบต์

FJ‘ṁ×⁸ẆZ€Ẇ€ẎŒPFQP$$ÐṀL€Ṃ

ลองออนไลน์! วิธีแก้ปัญหาความซับซ้อนของสนามกอล์ฟโดยทั่วไปไม่ต้องกังวลกับกรณีทดสอบที่ใหญ่กว่าพวกเขาจะหมดเวลา (กำลังตรวจสอบชุดพาวเวอร์ของสี่เหลี่ยมที่เป็นไปได้ทั้งหมด *)

อย่างไร?

รูปแบบสี่เหลี่ยมที่เป็นไปได้ทั้งหมดที่อาจจะทำ ใช้ชุดพลังงานของสี่เหลี่ยมเหล่านั้นและตรวจสอบเฉพาะการรักษาชุดเหล่านั้นซึ่งทั้งคู่ไม่มีเลขศูนย์และประกอบด้วยแต่ละชุดอย่างน้อยหนึ่งครั้ง

เพื่อให้บรรลุถึง "การรักษาเซตเหล่านั้นซึ่งทั้งคู่ไม่มีเลขศูนย์และมีแต่ละเซ็ตอย่างน้อยหนึ่งครั้ง" ส่วนรหัสแรกจะบังคับให้ชุดของจำนวนเต็มชัดเจนมากกว่าหนึ่งออกจากศูนย์เมื่อพวกมันกลายเป็น " การหาค่าสูงสุดของผลิตภัณฑ์ที่มีค่าไม่เหมือนใคร "

FJ‘ṁ×⁸ẆZ€Ẇ€ẎŒPFQP$$ÐṀL€Ṃ - Link: list of lists of ones and zeros, M
F                        - flatten M into a single list
 J                       - range of length = [1,2,3,...,len(flattened(M))]
  ‘                      - increment       = [2,3,4,...,len(flattened(M))+1]
   ṁ                     - mould like M - reshapes it just like M again
     ⁸                   - chain's left argument, M
    ×                    - multiply (vectorises) - unique integers > 1 at M's 1s and 0s at M's 0s
      Ẇ                  - non-empty sublists - i.e. row selections
       Z€                - transpose €ach
         Ẇ€              - non-empty sublists of €ach - column selections of those
           Ẏ             - tighten - a flat list of all of the rectangles
            ŒP           - power-set - all possible selections of rectangles
                   ÐṀ    - filter keep those for which the following is maximal:
                  $      -   last two links as a monad:
              F          -     flatten
                 $       -     last two links as a monad:
               Q         -       de-duplicate
                P        -       product
                     L€  - length of €ach - # of rectangles used by each full-cover
                       Ṃ - minimum

* สำหรับเมทริกซ์nโดยmนั่นคือวิธี (n, m) = 2 ^ (T (n) × T (m))ดังนั้น ...
วิธี (3,2) = 2 ^ ((3 + 2 + 1) × (2 + 1)) = 2 ^ 18 = 262,144 (ลิงก์ TIO)
วิธี (3,3) = 2 ^ ((3 + 2 + 1) × (3 + 2 + 1)) = 2 ^ 36 = 68,719,476,736
วิธี (3,4) = 2 ^ ((3 + 2 + 1) × (4 + 3 + 2 + 1)) = 2 ^ 60 = 1,152,921,504,606,846,976
วิธี (5,5) = 2 ^ 225 ~ = 5.4e + 67 (กรณีทดสอบที่ใหญ่ที่สุด)
วิธี (8,5) = 2 ^ 540 ~ = 3.6e + 162 (ตัวอย่าง)


จะFJṁ×⁸ẆZ€Ẇ€ẎŒPFQS$$ÐṀL€Ṃใช้กับ -1 ได้ไหม ไม่มีเวลาทดสอบ rn
Erik the Outgolfer

ไม่เพราะปกที่ถูกทอดทิ้ง (เท่านั้น) หนึ่งคนที่ถูกบังคับให้1มีผลิตภัณฑ์เดียวกันกับปกที่ถูกต้อง (เช่นเลี้ยวที่แปดจากห้าตัวอย่างครึ่งเทิร์นและมันจะกลับมา (ในทางทฤษฎี) 6ตามที่มันจะละเลยที่จะครอบคลุม เซลล์ซ้ายและพิจารณาว่าถูกต้อง)
Jonathan Allan

... ง่ายยิ่งขึ้น - กรณีทดสอบ[[1,0],[0,1]]จะกลับมามากกว่า1 2
Jonathan Allan

1

JavaScript, 434 ไบต์

รหัส:

for(_='),d=...-1||(,Ad<=a,u[o][n]=d,    =0,(e,r,C,m))&&()=>.map((h((A,n,on<e|o<r|n>C|o>mf=u=>(q(s=(e>C[e,C]=[C,e]r>m[r,m]=[m,r]lk=1,k&=!!A)kl|=&1,=2k&lh=f=>uA,$ABf(B,$))))(($,Bae=r=C=m=,d=to-Bt=n$&n>$e   C=nn+1~ee   C=ttn-$t=oB&o>Br    m=oo+1~rr   m=tq+=sg=[],h((ca||g.push(c)gigb,j(p=1,q+=i<j&&s(b)q)';G=/[-]/.exec(_);)with(_.split(G))_=join(shift());eval(_)

Hexdump (เนื่องจากอักขระที่ไม่สามารถพิมพ์ได้):

66 6F 72 28 5F 3D 27 29 2C 13 13 64 3D 12 2E 2E 2E 11 2D 31 10 7C 7C 28 0F 2C 41 0F 64 3C 3D 0E 61 2C 0C 75 5B 6F 5D 5B 6E 5D 0B 3D 64 2C 09 3D 30 2C 08 28 65 2C 72 2C 43 2C 6D 07 29 29 13 06 26 26 28 05 29 3D 3E 04 2E 6D 61 70 28 28 03 68 28 28 41 2C 6E 2C 6F 04 02 02 6E 3C 65 7C 6F 3C 72 7C 6E 3E 43 7C 6F 3E 6D 0F 01 66 3D 75 3D 3E 28 71 08 28 73 3D 07 04 28 65 3E 43 05 5B 65 2C 43 5D 3D 5B 43 2C 65 5D 13 72 3E 6D 05 5B 72 2C 6D 5D 3D 5B 6D 2C 72 5D 13 6C 08 6B 3D 31 2C 01 6B 26 3D 21 21 41 29 13 6B 05 01 6C 7C 3D 0B 26 31 2C 0B 3D 32 06 6B 26 6C 13 68 3D 66 3D 3E 75 03 41 2C 24 04 41 03 0C 42 04 66 28 0C 42 2C 24 29 29 29 29 28 28 0C 24 2C 42 04 61 10 0F 65 3D 72 3D 43 3D 6D 3D 10 2C 64 3D 74 08 02 6F 2D 42 0F 74 3D 6E 0E 24 26 6E 3E 24 05 65 09 43 3D 6E 10 12 6E 2B 31 06 7E 65 0F 65 09 43 3D 74 12 74 08 02 6E 2D 24 0F 74 3D 6F 0E 42 26 6F 3E 42 05 72 09 6D 3D 6F 10 12 6F 2B 31 06 7E 72 0F 72 09 6D 3D 74 13 71 2B 3D 73 07 06 67 3D 5B 5D 2C 68 28 28 0C 11 63 04 61 10 7C 7C 67 2E 70 75 73 68 28 63 29 13 67 03 0C 69 04 67 03 62 2C 6A 04 28 70 3D 31 2C 71 2B 3D 69 3C 6A 26 26 73 28 11 0C 11 62 29 06 71 29 27 3B 47 3D 2F 5B 01 2D 13 5D 2F 2E 65 78 65 63 28 5F 29 3B 29 77 69 74 68 28 5F 2E 73 70 6C 69 74 28 47 29 29 5F 3D 6A 6F 69 6E 28 73 68 69 66 74 28 29 29 3B 65 76 61 6C 28 5F 29

ลองออนไลน์!

มันไม่ได้กอล์ฟมาก แต่อย่างน้อยก็ทำงานได้เร็วมาก กรณีทดสอบทั้งหมดสามารถคำนวณได้ในไม่กี่มิลลิวินาที

Ungolfed

f=mat=>(
  iterate=f=>mat.map((A,x)=>A.map((a,y)=>f(a,y,x))),
  fill=(x1,y1,x2,y2)=>(
    x1>x2&&([x1,x2]=[x2,x1]),
    y1>y2&&([y1,y2]=[y2,y1]),
    isFilled=0,

    canBeFilled=1,
    iterate((A,X,Y)=>X<x1|Y<y1|X>x2|Y>y2||(
      canBeFilled&=!!A
    )),

    canBeFilled&&(
      iterate((A,X,Y)=>X<x1|Y<y1|X>x2|Y>y2||(
        isFilled|=mat[Y][X]&1,
        mat[Y][X]=2
      ))
    ),

    canBeFilled&isFilled
  ),

  rectangles=0,

  iterate((a,x,y)=>a-1||(
    x1=y1=x2=y2=-1,

    start=end=0,
    iterate((A,X,Y)=>Y-y||(
      end=X,
      A||(
        start<=x&X>x&&(x1=start,x2=X-1),
        start=X+1
      )
    )),
    ~x1||(x1=start,x2=end),

    start=end=0,
    iterate((A,X,Y)=>X-x||(
      end=Y,
      A||(
        start<=y&Y>y&&(y1=start,y2=Y-1),
        start=Y+1
      )
    )),
    ~y1||(y1=start,y2=end),

    rectangles+=fill(x1,y1,x2,y2)
  )),


  ones=[],
  iterate((a,...c)=>a-1||ones.push(c)),
  ones.map((a,i)=>ones.map((b,j)=>(
    M=1,
    rectangles+=i<j&&fill(...a,...b)
  ))),

  rectangles
)

คำอธิบาย

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

ในบางกรณี (เช่นในกรณีทดสอบ 16) มี1s ที่เหลือหลังจากใช้ขั้นตอนแรก จากนั้นแจกแจงทั้งหมดเหล่านี้1และใช้การค้นหาแบบ brute-force บางประเภท ขั้นตอนนี้ไม่ค่อยได้ถูกนำไปใช้และแม้แต่ในกรณีเหล่านี้เราจำเป็นต้องตรวจสอบแบบเดรัจฉานอย่างแรงเพียงชุดเดียวหรือสองชุดดังนั้นจึงควรทำงานอย่างรวดเร็วแม้สำหรับกรณีทดสอบขนาดใหญ่

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