Bìa hình chữ nhật tối thiểu


23

Bìa hình chữ nhật

Giả sử bạn có một ma trận các bit, ví dụ như sau.

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

Chúng tôi muốn tìm một bìa hình chữ nhật cho ma trận này. Nó là một tập hợp các tập con hình chữ nhật của ma trận không chứa bất kỳ 0 nào, nhưng cùng chứa tất cả các số 1. Các tập con không bắt buộc phải rời rạc. Dưới đây là một ví dụ về bìa hình chữ nhật cho ma trận trên.

+----+         +----+
|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|
+----+   +-------+   +-+

Số lượng hình chữ nhật trong bìa này là 7.

Nhiệm vụ

Đầu vào của bạn là một ma trận hình chữ nhật của các bit, được lấy ở bất kỳ định dạng hợp lý nào. Bạn có thể giả sử nó chứa ít nhất một 1. Đầu ra của bạn là số lượng hình chữ nhật tối thiểu trong một bìa hình chữ nhật của ma trận.

Số byte thấp nhất sẽ thắng. Luật tiêu chuẩn được áp dụng.

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

[[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

Đây có phải là cảm hứng từ bản đồ Karnaugh ?


@ThePirateBay cho bản đồ k tất cả các hình chữ nhật nên có kích thước hai chiều.
Sparr

@Sparr. Vâng, tôi biết điều đó. Tôi chỉ hỏi rằng nó có thể là nguồn cảm hứng cho thử thách này.

1
Trường hợp thử nghiệm hữu ích cho các cách tiếp cận tham lam : [[0,1,0,0],[0,1,1,1],[1,1,1,0],[0,0,1,0]], 4.
isaacg

Câu trả lời:


6

Python 2 , 318 315 271 byte

Mr.Xcoder, ovs và Jonathan Frech đã lưu rất nhiều byte

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

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


4

Thạch ,  25  24 byte

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

Hãy thử trực tuyến! Một giải pháp phức tạp cho golf điển hình, thậm chí không bận tâm với các trường hợp thử nghiệm lớn hơn, chúng sẽ hết thời gian (bộ sức mạnh của tất cả các hình chữ nhật có thể được kiểm tra *)

Làm sao?

Hình thành tất cả các hình chữ nhật có thể có thể được thực hiện. Lấy tập hợp sức mạnh của những hình chữ nhật đó và kiểm tra chúng chỉ giữ những bộ đó không chứa số không và chứa mỗi cái ít nhất một lần.

Để đạt được "giữ các tập hợp mà cả hai không chứa số 0 và chứa từng bộ ít nhất một lần", trước tiên, mã đó buộc các tập hợp thành một tập hợp các số nguyên khác nhau lớn hơn một, để các số không như vậy để chúng trở thành " tìm cực đại của sản phẩm của các giá trị duy nhất ".

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

* Đối với ma trận n by m đó là cách (n, m) = 2 ^ (T (n) × T (m)) , vì vậy ...
cách (3,2) = 2 ^ ((3 + 2 + 1) × (2 + 1)) = 2 ^ 18 = 262.144 (liên kết TIO)
(3,3) = 2 ^ ((3 + 2 + 1) × (3 + 2 + 1)) = 2 ^ 36 = 68,719,476,736
cách (3,4) = 2 ^ ((3 + 2 + 1) × (4 + 3 + 2 + 1)) = 2 ^ 60 = 1.152.921.504.606.846.976
cách (5,5) = 2 ^ 225 ~ = 5,4e + 67 (trường hợp thử nghiệm lớn nhất)
cách (8,5) = 2 ^ 540 ~ = 3.6e + 162 (ví dụ)


Sẽ FJṁ×⁸ẆZ€Ẇ€ẎŒPFQS$$ÐṀL€Ṃlàm việc cho -1? Không có thời gian để kiểm tra rn.
Erik the Outgolfer

Không, bởi vì một vỏ bọc bị bỏ qua (chỉ) một vỏ bọc bị ép buộc 1sẽ có cùng một sản phẩm như một vỏ bọc hợp lệ (ví dụ: xoay tám tám năm ví dụ một nửa lượt và nó (về lý thuyết) sẽ quay trở lại 6vì nó sẽ bỏ qua nắp trên -left cell và xem xét nó hợp lệ.)
Jonathan Allan

... thậm chí còn dễ dàng hơn - trường hợp thử nghiệm [[1,0],[0,1]]sẽ trở lại 1chứ không phải 2.
Jonathan Allan

1

JavaScript, 434 byte

Mã số:

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 (vì các ký tự không thể in):

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

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

Nó không phải là rất golf, nhưng ít nhất nó hoạt động rất nhanh. Tất cả các trường hợp thử nghiệm có thể được tính trong vài mili giây.

Bị đánh cắp

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
)

Giải trình

Nó sử dụng thuật toán tương tự như để giải các bản đồ Karnaugh. Đầu tiên, nó cố gắng tìm ít nhất một 1cái có thể là một phần của chính xác một hình chữ nhật không thể mở rộng. Ý tôi là không thể mở rộng nếu chúng ta mở rộng nó theo bất kỳ hướng nào (lên, trái, phải, xuống), nó sẽ bao gồm ít nhất một 0(hoặc sẽ vượt ra ngoài giới hạn ma trận). Khi 1tìm thấy như vậy , tìm hình chữ nhật lớn nhất bao gồm nó và gắn cờ tất cả 1s trong hình chữ nhật đó. Lặp lại cho đến khi không còn 1s không gắn cờ nào thỏa mãn các điều kiện này.

Trong một số trường hợp (như trong trường hợp thử nghiệm thứ 16) có những phần 1còn lại sau khi áp dụng bước đầu tiên. Sau đó liệt kê tất cả những thứ này 1và áp dụng một số loại tìm kiếm vũ phu nâng cao. Bước này hiếm khi được áp dụng, và ngay cả trong những trường hợp này, chúng ta chỉ cần kiểm tra vũ lực một hoặc hai kết hợp, vì vậy nó sẽ hoạt động rất nhanh ngay cả đối với các trường hợp thử nghiệm lớn hơn.

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.