L凸ですか?


14

バックグラウンド

ポリオミノが呼び出されたL-凸それはL字型パス、基本方向に行くと一度最大で方向を変えるパスで、他のタイルへのタイルから移動することができます場合、。たとえば1、図のs のポリオミノ

0 0 1 1 1 0

1 1 1 1 0 0

1 1 0 0 0 0

は、左下から1右上への両方のL字型パスに1aが含まれているため、L凸ではありません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つ含むことが保証されています1

出力

1s のセットが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

非常に素晴らしい挑戦、私はそれを楽しんだ=)
flawr

入力について:言語に配列がない場合改行区切り文字列が許可されますか?
edc65

@ edc65(申し訳ありませんが、数日グリッドから外れました。)もちろん、それも許されています。
ズガルブ

回答:


6

カタツムリ45 24

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

最初の解決策を投稿した直後に、はるかに優れた方法があることに気付きました。元のプログラムは、2つ1のsの間のパスによって形成された正方形の周りを移動し、辺の各ペアに0が存在するかどうかをテストしました。また、直線パスのための特別なケースが必要でした。新しいバージョンは1、一方から他方へテレポートし、1sの直線またはL字型のパスが存在しないことをテストして開始します。


ああ、神様!!これで遊ぶことができるオンライン通訳はありますか?
flawr

1
@flawrソースコードを使用して、ソースからビルドできます
アレックスA.

6

Matlab、182バイト

アイデア:1ポリオミノマトリックスのすべてについて繰り返します。

  • 与えられた1が、残りはゼロである新しい行列を作成します。
  • 1この新しいマトリックスのすべてに対して(何も変化しなくなるまで繰り返します)
    • 多項式に近傍としてある1場合、x方向に近傍として追加1
  • 1この新しいマトリックスのすべてに対して(何も変化しなくなるまで繰り返します)
    • 多項式に近傍としてある1場合、x方向に近傍として追加1

これ1で、新しいマトリックスでは1、最初にx方向に移動してから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バイト

わかりました、多分それは簡潔さのための賞を勝ち取らないでしょうが、それは新しいアプローチを使用します。それがどのように機能するかについては、未公開バージョンを参照してください。

この方法の証明は、Cellular Automata and Discrete Complex Systemsにあります。

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

@Zgarb記事は素晴らしく、数学的に指向していない人にとって意味のある数少ないものの1つです。
ジョージリース

2

Mathematica、129 127バイト

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

説明:

存在する場合は、最初は、0両者1は同一の行または列に、我々は、2つの接続できないため、アレイは、L凸ない1秒。

このケースを除外1すると、同じ行または列の2つごとに直線パスで接続できます。頂点が1配列内のs の位置であり、エッジが1同じ行または列上のsのペアであるグラフを生成できます。グラフの直径が3より小さい場合にのみ、配列はL凸になります。


1
これがどのように機能するのか説明できますか?私は誰も理解できないだろう=)
flawr

これにより、1番目と4番目の偽のインスタンス(切断されたインスタンス)がどのように認識されますか?
-Zgarb

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>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.