最大的广场


9

这个问题类似于网格中的最大广场

挑战

给定一个矩阵,该矩阵为,1并且0为字符串格式"xxxx,xxxxx,xxxx,xx.."或数组格式["xxxx","xxxx","xxxx",...],您将创建一个函数,该函数确定包含全部的最大正方形子矩阵的面积1

正方形子矩阵是宽度和高度相等的子矩阵,您的函数应返回仅包含的最大子矩阵的面积1

例如:

给定"10100,10111,11111,10010",这看起来像下面的矩阵:

1 0 1 0 0

1 0 1 1 1

1 1 1 1 1

1 0 0 1 0

您可以看到粗体字1创建了最大的2x2的正方形子矩阵,因此您的程序应返回面积为4的子矩阵。

规则

  • 子矩阵必须是宽度和高度相等的子矩阵之一
  • 子矩阵只能包含值 1
  • 您的函数必须返回最大子矩阵的面积
  • 如果找不到子矩阵,请返回 1
  • 您可以通过计算的数量计算子矩阵的区域1在子矩阵

测试用例

输入: "10100,10111,11111,10010" 输出: 4

输入: "0111,1111,1111,1111" 输出: 9

输入 "0111,1101,0111" 输出: 1


这是 ,因此以字节为单位的最短答案会获胜。


3
为什么是字符串格式?
Stewie Griffin

3
我们可以将输入作为二进制(数字)矩阵吗?
Stewie Griffin

5
对于[0],仍然需要输出1?
l4m2 '18

6
坚持一下,为什么在没有找到全1子矩阵的情况下返回1,那么0有意义吗?(否则,这只是处理的一个特殊情况)
Jonathan Allan

2
从目前的角度来看,我认为两个答复者都不会介意您是否更改了规范,我强烈建议您这样做,因为返回1没有意义,并且不会使提交的内容更加有趣。
ბიმო

Answers:


2

果冻,18 字节

+2处理“ all-all-1”子列表存在的输出

ẆZṡ¥"L€$ẎȦÐfL€Ṁ²»1

在线尝试!或查看测试套件

怎么样?

ẆZṡ¥"L€$ẎȦÐfL€Ṁ²»1 - Link: list of lists of 1s and 0s
Ẇ                  - all slices (lists of "rows") call these S = [s1,s2,...]
       $           - last two links as a monad:
     L€            -   length of each (number of rows in each slice) call these X = [x1, x2, ...]
    "              -   zip with (i.e. [f(s1,x1),f(s2,x2),...]):
   ¥               -     last two links as a dyad:
 Z                 -       transpose (get the columns of the current slice)
  ṡ                -       all slices of length xi (i.e. squares of he slice)
        Ẏ          - tighten (to get a list of the square sub-matrices)
          Ðf       - filter keep if:
         Ȧ         -   any & all (all non-zero when flattened?)
            L€     - length of €ach (the side length)
              Ṁ    - maximum
               ²   - square (the maximal area)
                »1 - maximum of that and 1 (to coerce a 0 found area to 1)

太棒了 你能补充一些解释吗?
路易斯·费利佩·德·耶稣·穆诺兹

我会,我想首先考虑较短的时间...
Jonathan Allan '18

@ Mr.Xcoder我已更新为现在处理需求
Jonathan Allan

5

Haskell中113个121 118 117字节

x!s=[0..length x-s]
t#d=take t.drop d
f x=last$1:[s*s|s<-min(x!0)$x!!0!0,i<-x!!0!s,j<-x!s,all(>'0')$s#i=<<(s#j)x,s>0]

在线尝试!

-3个字节感谢Laikoni

-1个字节感谢Lynn

+8个字节,对于所有全1s子矩阵都返回1的荒谬要求。

解释/取消

以下辅助函数仅创建偏移量,以x允许通过以下方式减少偏移量s

x!s=[0..length x-s]

x#y将从y列表中删除元素,然后采用x

t#d=take t.drop d

该函数f按顺序循环所有可能的子矩阵大小,生成相应大小的每个子矩阵,测试是否仅包含'1's并存储该大小。因此,解决方案将是列表中的最后一个条目:

--          v prepend a 1 for no all-1s submatrices
f x= last $ 1 : [ s*s
                -- all possible sizes are given by the minimum side-length
                | s <- min(x!0)$x!!0!0
                -- the horizontal offsets are [0..length(x!!0) - s]
                , i <- x!!0!s
                -- the vertical offsets are [0..length x - s]
                , j <- x!s
                -- test whether all are '1's
                , all(>'0') $
                -- from each row: drop first i elements and take s (concatenates them to a single string)
                              s#i =<<
                -- drop the first j rows and take s from the remaining
                                      (s#j) x
                -- exclude size 0...........................................
                , s>0
                ]

4

Haskell99 97字节

b s@((_:_):_)=maximum$sum[length s^2|s==('1'<$s<$s)]:map b[init s,tail s,init<$>s,tail<$>s]
b _=1

检查输入是否是一个带的方阵s==('1'<$s<$s),如果是,则答案为length ^ 2,否则为0。然后递归地砍掉第一列/最后一列/行,并取其在任何地方均可找到的最大值。

在线尝试!



3

J33 27字节

-6个字节感谢FrownyFrog!

[:>./@,,~@#\(#**/)@,;._3"$]

在线尝试!

说明:

我将在解释中使用第一个测试用例:

    ] a =. 3 5$1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1

我生成所有可能的正方形子矩阵,其大小从1到输入的行数。

,~@#\通过缝合输入,.的连续前缀的长度来创建子矩阵大小对的列表#\

   ,~@#\ a
1 1
2 2
3 3

然后,我用它们x u ;. _3 y将输入切成子矩阵。我已经有x(尺寸列表);y是正确的参数](输入)。

 ((,~@#\)<;._3"$]) a
┌─────┬─────┬─────┬───┬─┐
│1    │0    │1    │0  │0│
│     │     │     │   │ │
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│1    │0    │1    │1  │1│
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│1    │1    │1    │1  │1│
└─────┴─────┴─────┴───┴─┘

┌─────┬─────┬─────┬───┬─┐
│1 0  │0 1  │1 0  │0 0│ │
│1 0  │0 1  │1 1  │1 1│ │
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│1 0  │0 1  │1 1  │1 1│ │
│1 1  │1 1  │1 1  │1 1│ │
├─────┼─────┼─────┼───┼─┤
│     │     │     │   │ │
└─────┴─────┴─────┴───┴─┘

┌─────┬─────┬─────┬───┬─┐
│1 0 1│0 1 0│1 0 0│   │ │
│1 0 1│0 1 1│1 1 1│   │ │
│1 1 1│1 1 1│1 1 1│   │ │
├─────┼─────┼─────┼───┼─┤
│     │     │     │   │ │
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│     │     │     │   │ │
└─────┴─────┴─────┴───┴─┘

对于每个子矩阵,我检查其是否完全由1组成: (#**/)@,-展平矩阵,并根据其乘积明确地增加项目数。如果所有项目均为1,则结果将为其总和,否则-0:

   (#**/)@, 3 3$1 0 0 1 1 1 1 1 1
0
   (#**/)@, 2 2$1 1 1 1
4 

   ((,~@#\)(+/**/)@,;._3"$]) a
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1

0 0 0 0 0
0 0 4 4 0
0 0 0 0 0

0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

最后,我将每个子矩阵的结果列表放平并找到最大值:

>./@,

   ([:>./@,,~@#\(+/**/)@,;._3"$]) a
4

1
,~@#\"1 2->"$
FrownyFrog

@FrownyFrog谢谢!我不知道"$
Galen Ivanov '18

1
#比加1短。
FrownyFrog

@ FrownyFrog嗯,确实是。太好了,谢谢!
Galen Ivanov '18


2

视网膜,143字节

%`$
,;#
+%(`(\d\d.+;#)#*
$1¶$&¶$&#
\G\d(\d+,)|\G((;#+¶|,)\d)\d+
$1$2
)r`((11)|\d\d)(\d*,;?#*)\G
$#2$3
1,
#
Lv$`(#+).*;\1
$.($.1*$1
N`
-1G`
^$
1

在线尝试!链接包括测试用例。将输入作为逗号分隔的字符串。说明:

%`$
,;#

添加a ,终止最后一个字符串,a ;将该字符串与#s 分开,并添加a #作为计数器。

+%(`
)

重复该块,直到不再发生替换为止(因为每个字符串现在只有一位数字长)。

(\d\d.+;#)#*
$1¶$&¶$&#

重复三行,在第一行将计数器设置为1,在最后一行将其递增。

\G\d(\d+,)|\G((;#+¶|,)\d)\d+
$1$2

在第一行中,删除每个字符串的第一位数字,而在第二行中,删除除第一位之外的所有数字。

r`((11)|\d\d)(\d*,;?#*)\G
$#2$3

在第三行,按位与前两位数字在一起。

1,
#

在这一点上,每行包含两个值,a)一个水平宽度计数器,b)按位以及从每个字符串中提取的那么多位。将任何剩余的1s 转换为#s,以便可以将其与计数器进行比较。

Lv$`(#+).*;\1
$.($.1*$1

查找(垂直)与计数器匹配的所有位(垂直),与1原始输入中s的平方相对应,然后对长度求平方。

N`

按数字排序。

-1G`

拿最大的。

^$
1

特殊情况下为零矩阵。


2

JavaScript,92个字节

a=>(g=w=>a.match(Array(w).fill(`1{${w}}`).join(`..{${W-w}}`))?w*w:g(w-1))(W=a.indexOf`,`)||1


2

APL(Dyalog Classic)21 20字节

×⍨{1∊⍵:1+∇2×/2×⌿⍵⋄0}

在线尝试!


递归!真好!
扎卡里

@Zacharý谢谢。实际上,对于递归的f,我更喜欢k的f \ x之类的东西,而不是递归的,直到收敛为止,它一直是(x; fx; ffx; ...),但是APL中还没有等效项。用做它需要太多字节。
ngn

2

Python 2中117个 109字节

感谢@etene指出效率低下会浪费我一个额外的字节。

lambda s:max(i*i for i in range(len(s))if re.search(("."*(s.find(',')-i+1)).join(["1"*i]*i),s))or 1
import re

在线尝试!

将输入作为逗号分隔的字符串。这是一种基于正则表达式的方法,111.....111.....111对于所有可能的正方形大小,尝试将输入字符串与表单的模式进行匹配。

在我的计算中,使用匿名lambda进行此操作仅比定义的函数或完整程序短一点。最后的or 1部分仅在处理奇怪的边缘情况时才需要,在这种情况下,1如果输入中没有输入,则必须输出。


2

Python 2中116个 115 117 109字节

归功于@Kirill,他帮助我进一步打高尔夫球,并且他提供了聪明而又早期的解决方案

编辑:通过使用lambda打高尔夫球1个字节,我不知道将其分配给一个变量不计入字节数。

编辑2:基里尔指出我的解决方案不适用于输入仅包含1s的情况,我不得不修复它并丢失了两个宝贵的字节...

编辑3:多亏了基里尔的打高尔夫球

取一个逗号分隔的字符串,返回一个整数。

lambda g:max(i*i for i in range(len(g))if re.search(("."*(g.find(",")+1-i)).join(["1"*i]*i),g))or 1
import re

在线尝试!

我独立地找到了一个与Kiril的答案(即基于正则表达式)接近的答案,除了我使用re.search def之外。

它使用在每个循环期间构建的正则表达式来匹配更大的平方并返回最大的平方或1。


1
很好,我以某种方式自动放弃了这种if方法,因为它“肯定太久了”,但是随后不得不采取其他方法使比赛中的布尔值变得不那么合理。不幸的是,您的解决方案错过了一个点-您不能拥有公正range(l)-根本没有零的情况将错过。例如,采取第二个测试案例,并使其全部为1 -它应该不是9成为16
基里尔L.

该死,我考虑过用全零而不是全零进行测试(挑战中从未提到过……)。我会尽力弥补。
etene '18

@KirillL。顺便说一句,你很快!当您发布您的答案时,我仍在努力寻找答案;当我看到我们的方法很相似时,我感到有些沮丧(感到骄傲!)……这里的水平令人印象深刻。
etene '18

1
通过消除重复来打高尔夫球find。现在我们的代码不再相同了,我建议我们至少解决彼此之间明显的错误-在您的情况下,额外的字节来自使用元组("1"*i,)而不是列表。
Kirill L.

谢谢,是的,无用的元组对我而言非常愚蠢。另外find,那太聪明了。
etene



1

Python 2中138个 128字节

def f(m):j=''.join;L=j(m);k=map(j,zip(*m));return len(L)and max(len(L)*(len(m)**2*'1'==L),f(k[1:]),f(k[:-1]),f(m[1:]),f(m[:-1]))

在线尝试!


已保存

  • -10字节归功于ovs

1

Clojure,193个字节

#(apply max(for [f[(fn[a b](take-while seq(iterate a b)))]R(f next %)R(f butlast R)n[(count R)]c(for[i(range(-(count(first R))n -1)):when(apply = 1(for[r R c(subvec r i(+ i n))]c))](* n n))]c))

哇,事情升级了:

少打高尔夫球:

(def f #(for [rows (->> %    (iterate next)    (take-while seq)) ; row-postfixes
              rows (->> rows (iterate butlast) (take-while seq)) ; row-suffixes
              n    [(count rows)]
              c    (for[i(range(-(count(first rows))n -1)):when(every? pos?(for [row rows col(subvec row i(+ i n))]col))](* n n))] ; rectangular subsections
          c))
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.