矩形检测


21

编写一个包含0“ s”和1“ s ”的多行字符串的程序或函数。字符串中不会再有其他字符,并且字符串始终将是矩形的(所有行将具有相同数量的字符),尺寸小至1×1,但否则可以任意排列0'和1'。

您可以假设该字符串具有可选的尾随换行符,并且如果需要,可以使用任意两个不同的可打印ASCII字符代替01

打印或返回truthy值,如果所有的的路径连接的区域都0的和1的中的字符串是实心矩形,否则输出falsy值

路径连接区域0“是,从任何一个S是指0在该区域中,所有其它0的可以通过仅向上移动达到,下,左,右等0的(和倾斜地移动,移动到任何1不会超出字符串范围)。同样的想法适用于1路径连接区域。

实心矩形0的手段的矩形的整个区域被填充0的和没有1的。同样的想法适用于1实心矩形。

以字节为单位的最短代码获胜。抢七是较早的答案。

(请注意,字符串不会与环形边界条件一起环绕。)

例子

1)此输入字符串具有3个路径连接的区域(2个用于0,1个用于1)。但是,只有右下角的00区域是一个实心矩形,因此输出将是虚假的。

0011
0111
0100

2)该输入字符串具有4个路径连接的区域(2两者01)。它们都是实心矩形,因此输出将是真实的。

0011
0011
1100

3)此输入具有2条路径连接的区域,但其中只有一个是实心矩形,因此输出将是虚假的。

00000000
01111110
00000000

4)此输入只有1条路径连接的区域,并且是一个实心矩形,因此输出是真实的。

11111111
11111111
11111111

测试用例

T输入字符串下方的A 表示真实,F表示虚假。

0
T

1
T

00
T

01
T

10
T

11
T

0000000
T

1111111
T

011100100100101100110100100100101010100011100101
T

00
11
T

01
10
T

01
11
F

00
01
F

11
11
T

110
100
F

111
000
T

111
101
111
F

101
010
101
T

1101
0010
1101
0010
T

1101
0010
1111
0010
F

0011
0111
0100
F

0011
0011
1100
T

00000000
01111110
00000000
F

11111111
11111111
11111111
T

0000001111
0000001111
T

0000001111
0000011111
F

0000001111
1000001111
F

1000001111
1000001111
T

1110100110101010110100010111011101000101111
1010100100101010100100010101010101100101000
1110100110010010110101010111010101010101011
1010100100101010010101010110010101001101001
1010110110101010110111110101011101000101111
F

Answers:


5

果冻,7 个字节

ṣ⁷µ=ḢZE

这使用与@LevelRiverSt的Ruby answer相同的算法。实际算法适合最后4个字节;前3个字节是解析输入格式所必需的。

在线尝试!

怎么运行的

ṣ⁷µ=ḢZE  Main link. Argument: t (string)

ṣ⁷       Split t at linefeeds..
  µ      Begin a new, monadic link. Argument: A (list of strings)
    Ḣ    Pop the first string of A.
   =     Compare all other strings in A with the first.
         = compares characters, so this yields a list of Booleans for each string.
         For a truthy input, all pairs of lines now have been transformed in lists
         of only 1's or only 0's. That means all columns must be equal.
     Z   Zip; transpose rows with columns.
      E  Check if all rows (former columns) are equal to each other.

16

果冻11 10 字节

ṣ⁷^2\⁺€FS¬

非常感谢@Dennis将此高尔夫球打至原始尺寸的一半(通过未记录的功能)。

在线尝试!请注意,三重引号用于多行字符串。

说明

基本算法是:如果每个2x2子网格的偶数个数为1(或等效为0),则返回true。

很显然为什么奇数个1不能工作,因为我们将具有以下之一:

10  01  00  00  01  10  11  11
00  00  01  10  11  11  10  01

请注意,前4个是同一事物的旋转,后4个是同旋转的。反射角不能是矩形的一部分,因此为什么无效。

换句话说,所有2x2子网格都必须是以下之一:

00  00  11  01  10  01  10  11
00  11  00  01  10  10  01  11

如果我们看一下边界,可以想象为以下“拼图碎片”:

 ___    ___    ___    ___
|   |  | | |  |   |  | | |
|   |  | | |  |---|  |-|-|
|___|  |_|_|  |___|  |_|_|

并尝试与这些拼图块形成非矩形:)(两端匹配)

因此,实际的实现是:

ṣ⁷               Split input by newlines to give rows
  ^2\            Taking overlapping sets of 2 rows at a time: accumulate rows by XOR
                 Note that strings cast to integers automatically for bitwise operators
     ⁺€          Repeat the previous link (⁺), on each (€) element in the resulting array
       F         Flatten the array
        S        Sum (effectively reducing by OR)
         ¬       Logical negation of the result

例如,对于输入

100
010
000
101

我们有:

  ṣ⁷: ["100", "010", "000", "101"]
 ^2\: [[1, 1, 0], [0, 1, 0], [1, 0, 1]]    (e.g. first entry is "100" ^ "010")
^2\€: [[0, 1], [1, 1], [1, 1]]             (e.g. the first entry is [1^1, 1^0] - this
                                            gives the counts of 1s in each subgrid, mod 2)
   F: [0, 1, 1, 1, 1, 1]
   S: 5                                    (this gives the number of invalid 2x2 subgrids,
                                            which is indeed all but the top left)
   ¬: 0

1
您可以记录使用的功能吗?如果人们这样做,那么文档就会发生!
CalculatorFeline

您需要展平吗?
CalculatorFeline

@CatsAreFluffy如果您不展平,Jelly尝试对向量列表求和,结果得到一个向量
Sp3000

求和,求和-更好!
CalculatorFeline

4
“未记录的功能”-啊哈!这就是丹尼斯超越所有人的方式!:D
AdmBorkBork '16

12

Ruby,76岁

->s{j=!r=1
s.lines{|t|i=t.to_i(2)
j&&r&&=(j^i)%t.tr(?0,?1).to_i(2)<1
j=i}
r}

在完全由矩形组成的任何网格中,每行必须与之前的行相同,或者所有位都从0翻转到1,反之亦然。

这很容易证明。拿一张纸并在纸上画任意条垂直线和水平线。现在,仅使用2种颜色为矩形着色。您将最终得到变形的棋盘格,其中所有颜色在每一行都翻转。

是否要绘制仅部分穿过线的矩形?尝试删除任何一行的线段。现在,您将需要两种以上的颜色来为您的设计着色,因为您将拥有3个矩形相交的点(2个角和一条边)。因此,此类设计与该问题无关。

到目前为止,我还没有注意到这一点,这很令人惊讶。

我认为该算法在其他语言中应该短很多。

取消测试程序

f=->s{
  j=!r=1                              #r = truthy, j=falsy
  s.lines{|t|                         #for each line
    i=t.to_i(2)                       #i = value of current line, converted to a number in base 2 (binary)
    j&&                               #if j is truthy (i.e this is not the first line)
      r&&=(j^i)%t.tr(?0,?1).to_i(2)<1 #XOR i with the previous line. Take the result modulo (current line with all 0 replaced by 1)
                                      #if the result of the XOR was all 0 or all 1, the modulo == zero (<1). Otherwise, it will be a positive number.   
j=i}                                  #j = value of current line (always truthy in ruby, even if zero)
r}                                    #return 1 or true if all the modulo calculations were zero, else false.



#text to print after test case to check answer is as desired
T='T

'
F='F

'

#test cases
puts f['0'],T

puts f['1'],T

puts f['00
'],T

puts f['01'],T

puts f['10'],T

puts f['11
'],T

puts f['0000000'],T

puts f['1111111'],T

puts f['011100100100101100110100100100101010100011100101'],T

puts f['00
11'],T

puts f['01
10'],T


puts f['01
11'],F

puts f['00
01'],F

puts f['11
11
'],T

puts f['110
100'],F

puts f['111
000'],T

puts f['111
101
111'],F

puts f['101
010
101
'],T

puts f['1101
0010
1101
0010'],T

puts f['1101
0010
1111
0010'],F

puts f['0011
0111
0100
'],F

puts f['0011
0011
1100'],T

puts f['00000000
01111110
00000000'],F

puts f['11111111
11111111
11111111'],T

puts f['0000001111
0000001111'],T

puts f['0000001111
0000011111'],F

puts f['0000001111
1000001111'],F

puts f['1000001111
1000001111'],T

puts f['1110100110101010110100010111011101000101111
1010100100101010100100010101010101100101000
1110100110010010110101010111010101010101011
1010100100101010010101010110010101001101001
1010110110101010110111110101011101000101111'],F

我敢打赌s.scan(/^?.*\n/)会帮助节省字节。
并非查尔斯(Charles)

3

蜗牛,20字节

!{to{\0w`3\1|\1w`3\0

如果不存在带有3个零和一个1或3个与零0的2x2正方形,或者如果存在这样的2x2正方形,则打印网格的区域。


3

MATL,12字节

Ybc2thYCs2\~

@ sp3000的最佳答案相同的算法。

为了允许多行输入,MATL需要使用10换行符来显式构建行char数组(字符串)。因此,这四个示例的输入是(请注意[]是串联的,因此每个都是char的行数组):

['0011' 10 '0111' 10 '0100']
['0011' 10 '0011' 10 '1100']
['00000000' 10 '01111110' 10 '00000000']
['11111111' 10 '11111111' 10 '11111111']

最后三个测试用例是

['0000001111' 10 '1000001111']
['1000001111' 10 '1000001111']
['1110100110101010110100010111011101000101111' 10 '1010100100101010100100010101010101100101000' 10 '1110100110010010110101010111010101010101011' 10 '1010100100101010010101010110010101001101001' 10 '1010110110101010110111110101011101000101111']

Truthy输出是仅包含一个的数组。

在线尝试!

说明

这利用了一个事实,即char '0'和的奇偶校验与'1'数字0and 的奇偶校验相同1,因此无需从char转换为它表示的数字,

Yb     % split implicit input by whitespace. Gives a cell array
c      % concatenate cell contents into 2D char array
2th    % push array [2 2]
YC     % get 2×2 sliding blocks and arrange as columns
s      % sum of each column
2\     % modulo 2 of each sum
~      % negate. Implicit display

输入内容必须为字符串
卡尔文的爱好

@HelkaHomba MATL不允许多行字符串输入...输入必须是形式为的行数组['first line' 10 'second llne'],其中10换行符为ASCII。可以接受吗?
Luis Mendo

@HelkaHomba我在更新的答案中使用了它。或者,可以使用空格代替换行符吗?第一个示例是字符串'0011 0111 0100'
Luis Mendo

@ LuisMendo我很欣赏这个想法,但我认为Ruby的回答实际上可能对这里的高尔夫球手来说普遍:)
Sp3000

@ Sp3000哦,我还没看过那个。太聪明了
Luis Mendo

2

JavaScript(ES6),69个字节

s=>!s.split`
`.some((t,i,u)=>[...t].some((v,j)=>v^t[0]^u[0][j]^s[0]))

我认为,路径连通性矩形准则等同于要求给定形成任意矩形角的任何四个点均具有偶数1s。请注意,矩形(0,b),(x,y)的奇偶性与(0,b),(a,y)^(a,b),(x,y)相同,所以我只需要检查左上角为(0,0)的矩形。同样根据De Morgan的定律,!.some()它也为.every(!)我节省了几个字节。

编辑:我注意到,果冻解决方案检查所有2×2矩形的角的奇偶性,这可以证明是等效的。


差不多7次,但+1
edc65 '16

2

JavaScript(ES6),79

@ Sp3000中Jelly答案的相同算法(很高兴不必证明其有效)。只是8倍

s=>[...s].every((x,i)=>[++i,i+=s.search`
`,i+1].some(p=>!(x^=p=s[p],p>`
`))|!x) 

少打高尔夫球

s=>[...s].every((x,i)=> // repeat check for every sub square
     [++i,                  // array of position for next char in row
      i+=s.search`\n`, i+1] // and 2 chars at same column in next row
       .some(p=> // for each position 
          !( 
            x^=s[p],  // xor current value with value at position p
            s[p]>`\n` // true if value at position p is valid
           ) // the condition is negated
       ) // if any value scanned is not valid, .some return true
         // else, we must consider the check for current square
       | !x // x can be 0 or 1, to be valid must be 0
   ) 

测试套件

f=s=>[...s].every((x,i)=>[++i,i+=s.search`
`,i+1].some(p=>!(x^=p=s[p],p>`
`))|!x) 

testData=`
0
T

1
T

00
T

01
T

10
T

11
T

0000000
T

1111111
T

011100100100101100110100100100101010100011100101
T

00
11
T

01
10
T

01
11
F

00
01
F

11
11
T

110
100
F

111
000
T

111
101
111
F

101
010
101
T

1101
0010
1101
0010
T

1101
0010
1111
0010
F

0011
0111
0100
F

0011
0011
1100
T

00000000
01111110
00000000
F

11111111
11111111
11111111
T

0000001111
0000001111
T

0000001111
0000011111
F

0000001111
1000001111
F

1000001111
1000001111
T

1110100110101010110100010111011101000101111
1010100100101010100100010101010101100101000
1110100110010010110101010111010101010101011
1010100100101010010101010110010101001101001
1010110110101010110111110101011101000101111
F`

console.log=x=>O.textContent+=x+'\n'

testData.split('\n\n').forEach(t=>{
  var k=t.slice(-1)=='T',
      r=f(t.slice(0,-1))
  console.log(t+' '+r+ (k==r?' OK\n':' KO\n'))
})  
<pre id=O></pre>


1
现在延长8倍!
尼尔

1

Grime v0.1,31个字节

E=\0+|\1+
N=.+&E!
e`(E/N|N/E)#!

版画 1匹配和0不匹配。在线尝试!

说明

Grime是我的2D模式匹配语言。我今天确实做了修改,但只是为了更改语法元素的字符(`而不是,),因此它不会影响我的分数。

我正在使用与Sp3000相似的方法:如果输入包含2×N矩形,其中一行包含01,而另一行则没有,则输入是虚假的。

E=             Define a nonterminal E, which matches
  \0+|           a horizontal run of one or more 0s, OR
      \1+        a horizontal run of one or more 1s.
N=             Define a nonterminal N, which matches
  .+             a horizontal run of one or more characters,
    &E!          which is NOT matched by E (so contains both 0 and 1).
e`             Match entire input to this pattern:
            !    not
           #     contains
  (E/N|N/E)      E on top of N, or N on top of E

1

JavaScript(ES6),64字节

s=>(a=s.split`
`).every(l=>l==a[0]|l==a[0].replace(/./g,n=>n^1))

基于@LevelRiverSt的观察,即每行必须与第一行相同或相反。

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.