是L凸的吗?


14

背景

四角被称为L-凸,如果有可能从任何瓦到任何其他瓦片行程由L形路径,即,云在基本方向并且至多一次改变方向的路径。例如,1图中的s 的多米诺骨牌

0 0 1 1 1 0

1 1 1 1 0 0

1 1 0 0 0 0

不是L凸的,因为从左下角1到右上角的两个L形路径1都包含0

0>0>1>1>1 0
^       ^
1 1 1 1 0 0
^       ^
1>1>0>0>0 0

但是,1此图中s 的多米诺是L凸的:

0 1 1 1 0 0

1 1 1 1 1 1

0 1 1 0 0 0

输入值

您的输入是2D的位数组,采用您的语言的本机格式,如果我们的语言缺少数组,则以换行符分隔的字符串形式输入。确保至少包含一个1

输出量

如果1s 的集合是L凸的多米诺骨牌,则您的输出应为真值,否则为f。这些输出必须是一致的:对于所有L凸输入,您必须输出相同的真实值,而对于其他L-凸输入,则必须输出相同的假值。请注意,一组断开连接的1s(不是polyomino)会导致错误的输出。

规则和计分

您可以编写完整的程序或函数。最低字节数获胜,并且不允许出现标准漏洞

测试用例

如果旋转或反射数组,或将0s 行添加到任何边界,这些测试用例也应起作用。

False instances
01
10

111
101
111

1101
1111
1110

1100
1000
0011

01100
11110
01110
00110

011000
011110
001111

True instances
1

01
11

010
111
010

001
011
111

11100
11110
01100
01000

011000
011000
111100
111111
001000

非常好的挑战,我很喜欢(=)
瑕疵的,2015年

关于输入:如果我们的语言缺少数组允许使用换行符分隔的字符串
edc65

@ edc65(对不起,停运了几天。)当然,这也是允许的,但我的意思很不好。
Zgarb 2015年

Answers:


6

蜗牛45 24

&
!{\1t\1!{o\1,nf\1,!.!~

在发布最初的解决方案后,我立即意识到有更好的方法。原始程序绕着由两个1s 之间的路径形成的正方形移动,测试每对边中是否存在0。直线路径也必须有特殊情况。新版本首先从一个端口1传到另一个端口,然后测试1s 是否没有直线或L形路径回到起点。


我的天啊!!有没有在线翻译人员可以解决这个问题?
flawr

1
@flawr您可以在此处使用源代码从源代码构建它。
Alex A.

6

Matlab,182字节

想法:1对多米诺矩阵中的每个重复:

  • 仅使用给定的矩阵创建新矩阵 1但其余为零的。
  • 每个 1此新矩阵中的矩阵(重复进行,直到不再更改为止)
    • 1如果1多项式中存在邻居,则在x方向上添加邻居
  • 每个 1此新矩阵中的矩阵(重复进行,直到不再更改为止)
    • 1如果1多项式中存在邻居,则在x方向上添加邻居

现在1,在新矩阵中,应该覆盖1从第一个方向开始然后在y方向上从给定起点可到达的所有多项式矩阵。现在我们可以重复相同的过程,但首先要进入y方向,然后进入x方向。现在1应该一次或两次都到达每个多氨基酸矩阵。如果不是,则我们在多项式矩阵中找到了一个位置,该位置不能通过其他位置从每个其他位置到达L -path。

打高尔夫球:

function r=f(a);[i,j,b]=find(a);N=nnz(i);r=1;for k=1:N;K=1:3;for l=1:2;c=b;b=a*0;b(i(k),j(k))=1;for z=1:2*N; b=conv2(b+0,K,'s')&a;if z==N;K=K';end;end;end;r=r*all(b(:)|c(:)>=a(:));end

有评论:

function r=codegolf_L_convex(a);
%a=[0,1;1,1];
[i,j,b]=find(a);%b just needs to be initialized, does not really mattter
N=nnz(i);%number of ones in the matrix
r=1;%return value
for k=1:N;%go throu all '1' in the matrix
    %expand that pixel in x dir:
    K=1:3;%convolution kernel (just three positive values needed)
    for l=1:2;%first horizontal->vertical then vertical->horizontal
        c=b;%backup for considering both runs
        b=a*0;
        b(i(k),j(k))=1; %set the seed
        for z=1:2*N;     
            b=conv2(b+0,K,'s')&a; %expand the seed horizontally (or vertically for the second half) but only within the polyomino
            if z==N;
                K=K'; %change horizontal/vertical 
            end;
        end;
    end;
    r=r*all(b(:)|c(:)>=a(:));%check whether we can really reach every point
end

测试用例脚本:

disp('all false -------------');
a=[0,1;1,0];
f(a)
a=[1,1,1;1,0,1;1,1,1];
f(a)
a=[1,1,0,1;1,1,1,1;1,1,1,0];
f(a)
a=[1,1,0,0;1,0,0,0;0,0,1,1];
f(a)
a=[0,1,1,0,0;1,1,1,1,0;0,1,1,1,0;0,0,1,1,0];
f(a)
a=[0,1,1,0,0,0;0,1,1,1,1,0;0,0,1,1,1,1];
f(a)
 disp('all true +++++++++++++');
a=[1];
f(a)
a=[0,1;1,1];
f(a)
a=[0,1,0;1,1,1;0,1,0];
f(a)
a=[0,0,1;0,1,1;1,1,1];
f(a)
a=[1,1,1,0,0;1,1,1,1,0;0,1,1,0,0;0,1,0,0,0];
f(a)
a=[0,1,1,0,0,0;0,1,1,0,0,0;1,1,1,1,0,0;1,1,1,1,1,1;0,0,1,0,0,0];
f(a)

2

Javascript ES6,290个字节

好的,也许它不会赢得任何简短奖励,但是它确实使用了一种新颖的方法。有关工作原理,请参见非公开版本。

该方法的证明可在以下文献中找到:元胞自动机和离散复杂系统

L=a=>[1,0,1].every($=>(a=a[0].map((_,col)=>a.map(row=>row[col]))).map(r=>($?r.reverse():r).join``).every((r,i,b)=>r.replace(/^(0*)(1*)(0*)$|(.+)/,(_,s,m,o,e)=>(c=e)?'':!m||b[i-1]&&+b[i-1][s.length]?1:b.every((r,j)=>j<i||(c=c||!+r[l=s.length])?r.search(`0{${l}}.*0{${o.length}}`)+1:1)||'')))

取消高尔夫:

function L(a) {
  /* Runs three times and ensure all pass validation
   * 1: horizontally reversed
   * 2: 90 degrees rotated
   * 3: original
   *
   *     | 1:  | 2:  | 3:
   * =====================
   * 001 | 100 | 111 | 001
   * 011 | 110 | 011 | 011
   * 111 | 111 | 001 | 111
   *
   * By finding maximal rectangles with corners on all NW and NE corners
   * (separately) of a HV-convex polyomino and ensuring it doesn't enter the
   * boundaries labelled ABCD for the rectangle X below:
   *
   *   A  |         |  B
   * -----===========-----
   *      |    X    |
   * -----===========-----
   *   C  |         |  D
   *
   * The first iteration tests the NE corners and horizontal convexity.
   * The second iteration test vertical convexity.
   * The third iteration tests the NW corners.
   *
   * If all pass then the polyomino is L-convex.
   */
  return [1,0,1].every(function($){
    return (a=a[0].map((_,col)=>{
      // Transpose rows with columns
      return a.map(row=>row[col])
    })).map(row=>{
      // Join rows as strings and on odd iterations reverse them
      return ($ ? row.reverse() : row).join``
    }).every(function(row, i, b) {
      if (i == 0) console.log(b.join('\n'));
      return row.replace(/^(0*)(1*)(0*)$|(.+)/, function(_, start, middle, end, invalid) {
        // Non H-convex polyomino (0 between 1s)
        if (invalid) return '';
        // Is not a NW corner (character above is 1)
        if (!middle || b[i-1] && +b[i-1][start.length]) return 1;
        c=1;
        return b.every(function(row, j) {
          // Above or below maximal rectangle from corner
          if (j < i || !(c=c&&+row[l=start.length])) {
            // Area before and after maximal rectangle doesn't contain 1
            return row.search(`0{${l}}.*0{${end.length}}`)+1
          }
          return 1;
        }) || '';
      });
    });
  });
}

1
哈,那篇文章正是我受此挑战启发的地方!
Zgarb 2015年

@Zgarb这篇文章很棒,也是我发现对那些数学上不熟练的人有意义的少数文章之一。
乔治·瑞斯

2

Mathematica, 129 127字节

3>GraphDiameter@Graph[#,#<->#2&@@@Select[#~Tuples~2,!FreeQ[#-#2&@@#,0]&]]&@Position[#,1]&&{#,Thread@#}~FreeQ~{___,1,0..,1,___}&

说明:

首先,如果有 01在同一行或同一列上的两个s 之间,则该数组不是L凸的,因为我们无法连接两个1s。

排除这种情况后,1同一行或同一列上的每两个可通过一条直线路径连接。我们可以生成一个图,其顶点是1s在数组中的位置,边是1同一行或同一列上的s对。当且仅当图形的直径小于3时,数组才是L凸的。


1
您能解释一下这是如何工作的吗?我不会
赞扬

如何识别第一个和第四个错误实例(断开连接的实例)?
Zgarb 2015年

1
@Zgarb如果图形断开连接,则其直径为无穷大。
alephalpha

2

JavaScript(ES6)174

查看空的或填充的单元格的网格,对于任何一对填充的单元格,我检查到另一单元格列的水平路径(如果单元格在同一行上则可以为1,否则为2)以及到单元格的垂直路径。其他单元格行(也可以是1或2)。如果我在两个垂直路径或两个水平路径中都找到一个空的单元格,那么在这些单元格之间就不会有L形的路径。

(我很难提出这个解释-希望我已经清楚了)

在任何符合EcmaScript 6的浏览器中测试运行以下代码段

F=p=>!p.some((n,y)=>n.some((q,x)=>q&&p.some((o,u)=>o.some((q,t)=>{for(f=0,i=y;q&i<=u;i++)f|=!p[i][x]|2*!p[i][t];if(f<3)for(f=0,j=x;q&j<=t;j++)f|=!n[j]|2*!o[j];return f>2}))))

// TEST
console.log=(...x)=>O.innerHTML+=x+'\n'

tko = [
 [[0,1],[1,0]]
,[[1,1,1],[1,0,1],[1,1,1]]
,[[1,1,0,1],[1,1,1,1],[1,1,1,0]]
,[[1,1,0,0],[1,0,0,0],[0,0,1,1]]
,[[0,1,1,0,0],[1,1,1,1,0],[0,1,1,1,0],[0,0,1,1,0]]
,[[0,1,1,0,0,0],[0,1,1,1,1,0],[0,0,1,1,1,1]]
]
tko.forEach(t=>(console.log(t.join`\n`+`\nFalse? ${F(t)}\n`)));
tok = [
 [[1]]
,[[0,1],[1,1]]
,[[0,1,0],[1,1,1],[0,1,0]]
,[[0,0,1],[0,1,1],[1,1,1]]
,[[1,1,1,0,0],[1,1,1,1,0],[0,1,1,0,0],[0,1,0,0,0]]
,[[0,1,1,0,0,0],[0,1,1,0,0,0],[1,1,1,1,0,0],[1,1,1,1,1,1],[0,0,1,0,0,0]]
]  
tok.forEach(t=>(console.log(t.join`\n`+`\nTrue? ${F(t)}\n`)));

// LESS GOLFED

U=p=>
  !p.some((n,y)=>  
    n.some((q,x)=> 
      q && p.some((o,u)=>  
        o.some((q,t)=>{
          for(f=0,i=y; q&i<=u; i++)f|=!p[i][x]|2*!p[i][t]
          if (f<3)
            for(f=0,j=x; q&j<=t; j++)f|=!n[j]|2*!o[j]
          return f>2
        })
      )
    )
  )
<pre id=O></pre>

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.