L-dışbükey mi?


14

Arka fon

Bir polyominoya L-konveks denir , eğer herhangi bir kiremitten başka bir kiremite L şeklinde bir yolla, yani kardinal yönlere giden ve en fazla bir kez yön değiştiren bir yolla seyahat etmek mümkünse. Örneğin 1, şekildeki s poliomino

0 0 1 1 1 0

1 1 1 1 0 0

1 1 0 0 0 0

L-dışbükey değildir, çünkü sol alttan 1sağ üste doğru her iki L şekilli yol 1da 0şunları içerir :

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

Bununla birlikte, 1bu şekilde s'nin polomino L-dışbükeydir:

0 1 1 1 0 0

1 1 1 1 1 1

0 1 1 0 0 0

Giriş

Girişiniz, dilinizin yerel biçimindeki 2B bir bit dizisidir veya dilimiz diziler içermiyorsa, yeni satırla sınırlandırılmış bir dizedir. En az bir tane içermesi garanti edilir 1.

Çıktı

Eğer 1s kümesi bir L-dışbükey polimino ise, çıktınız gerçek bir değer, değilse bir yanlış değer olmalıdır. Bu çıktılar tutarlı olmalıdır: tüm L-konveks girişler için aynı doğruluk değerini ve diğerleri için aynı yanlış değeri vermelisiniz. Bağlantısı kesilmiş bir 1s grubunun ( bir poliomino olmayan) bir tahrifat çıktısı verdiğini unutmayın.

Kurallar ve Puanlama

Tam bir program veya bir işlev yazabilirsiniz. En düşük bayt sayısı kazanır ve standart boşluklara izin verilmez.

Test Durumları

Bu test senaryoları, dizileri döndürürseniz veya yansıtırsanız veya 0herhangi bir sınıra s satırları eklerseniz de çalışmalıdır .

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

Çok güzel bir meydan okuma, çok memnun oldum =)
flawr

Girişi hakkında: Bir satır ayrılmış dize , izin dilimizi eğer gelmez diziler eksikliği ?
edc65

@ edc65 (Üzgünüm, birkaç gündür şebekeden çıkmış.) Elbette, buna da izin veriliyor, benim açımdan çok kötü ifade edildi.
Zgarb

Yanıtlar:


6

Salyangoz , 45 24

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

İlk çözümümü gönderdikten hemen sonra, çok daha iyi bir yol olduğunu fark ettim. Orijinal program 1, her iki çiftte 0 olup olmadığını test ederek iki s arasındaki yolların oluşturduğu karenin etrafında dolaştı . Ayrıca düz çizgi yolları için özel bir durum olması gerekiyordu. Yeni sürüm, birinden 1diğerine ışınlanarak ve başlangıcına kadar düz veya L şeklinde bir yol olup olmadığını test 1ederek başlar.


AMAN TANRIM!! Bununla oynayabileceğimiz bir çevrimiçi tercüman var mı?
flawr

1
@flawr Burada kaynak kod ile kaynaktan oluşturabilirsiniz .
Alex A.

6

Matlab, 182 bayt

Fikir: 1Polyomino matrisindeki her biri için tekrarlayın :

  • Sadece verilen 1ancak geri kalan sıfır ile yeni bir matris oluşturun .
  • 1bu yeni matristeki herkes için (artık hiçbir şey değişmeyene kadar tekrarlayın)
    • polinomda komşular 1varsa x yönünde komşular ekleyin1
  • 1bu yeni matristeki herkes için (artık hiçbir şey değişmeyene kadar tekrarlayın)
    • polinomda komşular 1varsa x yönünde komşular ekleyin1

Şimdi 1yeni matriste, 1önce x-yönünde ve sonra y-yönünde giderek belirli bir başlangıç ​​noktasından ulaşılabilen polinomio-matrisin tümünü kapsamalıdır . Şimdi aynı işlemi tekrarlayabiliriz, ancak önce y-yönüne, sonra x-yönüne gideriz. Şimdi her bir 1polyomino matrisine bir kerede veya her ikisine de ulaşılmalıdır. Değilse, polinomio matrisinde bir L-yol ile diğer her konumdan ulaşılamayan bir pozisyon bulduk .

golfed:

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

Yorumlarla:

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

Test senaryoları komut dosyası:

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 bayt

Tamam, belki kısalık için herhangi bir ödül kazanmaz, ancak yeni bir yaklaşım kullanır. Nasıl çalıştığını öğrenmek için ungolfed sürümüne bakın.

Bu yöntemin kanıtı şurada bulunabilir: Hücresel Otomata ve Ayrık Kompleks Sistemler .

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)||'')))

Ungolfed:

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
Ha, bu makale bu meydan okuma için ilham aldığım yer!
Zgarb

@Zgarb Makale harikaydı ve matematiksel yönelimli olmayan biri için mantıklı bulabildiğim birkaç kişiden biri.
George Reith

2

Mathematica, 129 127 bayt

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

Açıklama:

Birincisi, aynı satır veya sütunda 0iki 1s arasındaysa , dizi L-dışbükey değildir, çünkü iki 1s'yi bağlayamayız .

Bu durum hariç tutulduktan sonra 1, aynı satır veya sütundaki her iki s düz bir yolla bağlanabilir. Köşeleri 1dizideki s konumları ve kenarları 1aynı satır veya sütundaki s çiftleri olan bir grafik oluşturabiliriz . Daha sonra dizi, yalnızca grafiğin çapı 3'ten küçükse L-konveks olur .


1
Bunun nasıl çalıştığını açıklayabilir misiniz? Kimsenin anlayamadığı anlamsızlıktan bahsetmeyeceğim =)
flawr

Bu, ilk ve dördüncü yanlış örnekleri (bağlantısız olanları) nasıl tanır?
Zgarb

1
@Zgarb Grafik bağlantısı kesilirse, çapı sonsuzdur.
alephalpha

2

JavaScript (ES6) 174

Boş veya doldurulmuş hücrelerin ızgarasına baktığımda, herhangi bir dolu hücre çifti için diğer hücre sütununun yatay yollarını kontrol ediyorum (hücreler aynı satırda ise 1 olabilir, başka veya 2) ve dikey yollarda diğer hücre sırası (1 veya 2 de olabilir). Her iki dikey yolda veya her iki yatay yolda boş bir hücre bulursam, hücreler arasında L şeklinde bir yol olamaz.

(Bu açıklamayı yapmaya çalışırken zorlandım - umarım net olmalıyım)

Aşağıdaki snippet'i herhangi bir EcmaScript 6 uyumlu tarayıcıda çalıştırmayı test edin

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>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.