将网格拆分为网格


22

介绍

有一个小村庄,只有几栋房子和空旷的田野。当地官僚希望将村庄分成很多部分,以便每个地块都包含一所房子,并且地块的边界形成一个漂亮的直线网格。您的任务是确定是否可行。

任务

您的输入是一个矩形的二维位数组;1代表房屋,0代表空字段。它的大小将至少为1×1,并且将至少包含1个1。您可以采用任何合理格式的输入(嵌套的整数列表,字符串列表,多行字符串等)。

您的程序将确定是否可以使用水平和垂直直线将数组划分为多个网格单元,以便每个网格单元仅包含一个1。网格单元可能具有不同的大小和形状,尽管它们始终是矩形。这些线必须从阵列的一条边缘延伸到另一条边缘。

例如,以下是数组的有效划分:

00|0010|01|1
01|0000|00|0
--+----+--+-
00|0000|00|1
01|0010|01|0
--+----+--+-
01|1000|10|1

而以下划分是无效的,因为存在没有1或多个1的网格单元:

00|0010|01|1
--+----+--+-
01|0000|00|0
00|0000|00|1
01|0010|01|0
--+----+--+-
00|1000|10|1

如果存在有效的除法,则应输出真实值,否则输出虚假值。

规则和计分

您可以编写完整的程序或函数。最低字节数获胜。

测试用例

[[1]] -> True
[[0,1],[1,0]] -> True
[[1,1],[1,0]] -> False
[[1,0,1],[0,1,0]] -> True
[[1,0],[0,1],[0,1]] -> True
[[1,0,0],[0,0,1],[0,1,1]] -> True
[[1,1,1],[1,1,1],[1,1,1]] -> True
[[1,0,1],[0,1,0],[1,0,0]] -> True
[[1,0,0],[1,0,0],[0,1,1]] -> False
[[0,0,0,0,1],[1,0,0,1,0],[0,0,0,1,0]] -> False
[[0,0,1,0,1],[0,0,0,1,0],[0,0,0,0,0]] -> True
[[1,1,0,0,0],[0,0,0,0,0],[1,0,1,0,0]] -> True
[[1,1,0,1,1],[0,1,0,1,1],[1,0,0,0,0]] -> True
[[0,0,0,0,0,0,0],[0,1,1,1,0,1,0],[0,1,0,0,1,0,0],[0,0,0,0,0,0,1],[0,0,1,0,0,0,1],[1,1,0,1,1,0,0]] -> False
[[1,1,0,0,0,0,0],[1,0,1,1,0,1,0],[0,0,0,0,1,0,0],[0,1,0,1,1,0,0],[1,0,0,0,1,1,0],[0,0,0,0,0,1,0]] -> False
[[0,1,0,1,1,1,0],[0,0,0,0,1,0,0],[0,0,0,0,0,0,0],[1,0,0,1,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,1]] -> True
[[0,1,0,0,1,0,1],[1,0,0,0,1,0,1],[0,0,1,0,1,0,1],[1,0,0,0,1,1,0],[0,0,0,1,1,1,0],[0,1,0,0,1,0,1]] -> True
[[0,1,0,0,1,0,0,1,0],[0,0,0,0,1,1,0,1,0],[1,1,0,0,1,0,0,0,0],[0,0,1,0,1,0,1,0,0],[0,0,1,0,1,0,1,0,0],[0,1,0,0,0,1,0,0,1],[0,1,0,0,0,0,1,0,0]] -> False
[[1,0,1,0,0,1,1,0,1],[0,1,1,0,0,1,1,0,1],[1,0,0,0,0,1,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,1,0,0,0,0,1,1],[0,1,1,0,1,0,1,0,1],[1,0,1,0,0,1,1,0,1]] -> True

可以将[[0,0,1,0,1],[1,0,0,1,0],[0,0,0,1,0]]分为:3X1、2X1、3X2、2X1, 2X1矩形是否以这种方式?001 | 01 --- +-100 | 10 +-000 | 10
Officialaimm

4
@officialaimm不,那是无效的。网格线必须从阵列的一侧一直延伸到另一侧。
Zgarb

建议的测试用例:[[1, 0, 1], [0, 1, 0], [1, 0, 0]]那是我的新方法失败的唯一3x3矩阵。
丹尼斯

@丹尼斯谢谢,补充。
Zgarb

Answers:


7

Pyth,30 29 26 24 23字节

sm.Asmmq1ssbCkds./MC./M

在线尝试。

我相信这会变得更短。这是O(2 mn,其中mn是数组的宽度和高度,但是使用电池供电的笔记本电脑(性能有限的i5-5200U)在45秒内完成了最后两个测试用例。

输出解决方案的数量。

说明

五维数组真的很有趣。</ sarcasm>即使有解释,您也不应该了解其工作原理。

                    ./M    Find all partitions of each row. Now we have a list of rows,
                           each containing the ways to split the row, each containing
                           the parts of the split (3D).
                   C       Transpose. Now we have a list of ways to split the columns,
                           each containing the rows, each containing the parts of the
                           row (3D).
                ./M        Find all partitions of each row list. Now we have a list of
                           ways to split the columns, each containing the ways to split
                           the rows, each containing the bunch of rows, each containing 
                           the rows in the bunch, each containing the parts of the row
                           (6D).
               s           Combine the ways to split rows & columns into one array (5D).
 m            d            Do the following for each way to split rows & columns (4D):
     m       k                 Do the following for each bunch of rows (3D):
            C                      Transpose the array. We now have a list of column
                                   groups, each containing the row parts (3D).
      m    b                       Do the following for each column group (2D):
          s                            Combine the row parts in the column group. We now
                                       have the list of cells in this row/column group
                                       (1D).
         s                             Sum the cells.
       q1                              Check if the sum is one.
                                   We now have the list of booleans that tell if each
                                   row/column group is valid (1D).
                               We now have the 2D list of booleans that tell if each
                               row/column group in each bunch of rows is valid. (2D)
    s                          Combine the 2D list of booleans to 1D.
  .A                           Check if all values are truthy; if the split is valid.
                           We now have the validity of each split.
s                          Sum the list to get the number of valid solutions.


2

Haskell,116字节

import Data.List
m(a:b)=[a:e|e<-m b]++[zipWith(+)a d:e|d:e<-m b];m e=[e]
d=(any$any$all$all(==1)).map(m.transpose).m

在线尝试!


1
这不会编译。请删除您的答案,直到确定为止。还有很多打高尔夫球的潜力。重命名mergerowsm
Laikoni '17

由于Pyth难以击败,我计划退出比赛,并感谢您@Laikoni发现我很可能弄乱了我的压痕支架。
Roman Czyborra

2
这错误地给False [[1,0],[0,1],[1,0]]。问题在于贪婪的崩溃会阻碍以后更好的崩溃。
xnor

确实,我的 [[1,1],[1,0]]崩溃错误地阻碍了[[1],[1],[1]]解决方案。让我睡一会还是删除?
Roman Czyborra


1

果冻,20字节

ŒṖS€€ỊȦ$ÐfZ€µ⁺€Ȧ€€FS

这仍然是一个蛮力的解决方案,但是它比我的其他答案要快得多,后者不能应付TIO上的最后两个测试用例,并且可以在约4秒钟内处理所有测试用例。

在线尝试!

怎么运行的

ŒṖS€€ỊȦ$ÐfZ€µ⁺€Ȧ€€FS  Main link. Argument: M (matrix, array of rows)

ŒṖ                    Compute all partitions, i.e., all groupings of M's rows.
  S€€                 Map sum over all individual groupings, collapsing the grouped
                      rows into a single row.
        Ðf            Filter; keep only those partially collapsed matrices for
                      which the link to the left returns a truthy value.
       $                Group the two links to the left into a monadic chain.
     Ị                    Insignificant; map 0 and 1 to 1, greater integers to 0.
      Ȧ                   All; return 1 iff the matrix contains no zeroes.
          Z€          Zip/transpose all kept matrices,
            µ         Combine all links to the left into a monadic chain.
             ⁺€       Duplicate the chain and map it over the individual results
                      from the first call. We now have all possible combinations
                      of row and column groupings (represented by the corresponding
                      matrices of collapsed rows and columns) that do not have a
                      2 anywhere. However, they still may contain zeroes.
               Ȧ€€    Map the all atom over the matrices, returning 1 only for
                      matrices that consist entirely of ones.
                  FS  Flatten and sum, counting the number of valid divisions.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.