Izgaralar kıvrımlı olabilir. Seninki ne kadar


12

W genişliğinde H yüksek metin ızgarasında , eğrinin bir bölümünü temsil eden ve boş alanı temsil eden ve başka hiçbir karakter kullanılmayan basit , açık , iki boyutlu bir eğri tasvir etmeyi düşünün .X.

Her ızgara alanında 8 komşu ızgara alanı, Moore mahallesi var . Sınırların ötesindeki ızgara boşlukları boş kabul edilir.

Bir ızgarada tam olarak bir VEYA varsa birden fazla varsa bir eğri bulunur :X X

  • Tam olarak iki Xs sadece bir komşusu vardır X. Bunlar eğrinin uç noktalarıdır.
  • Her Xbitiş noktaları komşuları tam iki yanında Xs. Bunlar eğrinin büyük kısmını oluşturur.

Örneğin, W = 9 ve H = 4 olan bu ızgara bir eğri içerir:

....X....
.X.X.X.X.
X..X..X.X
.XX.....X

Benzer şekilde, bu ızgaraların (W = 4, H = 3) eğrileri vardır:

....  .X..  ....  ....  .X.X
....  X..X  ..X.  XX..  X.X.
..X.  .XX.  .X..  ....  ....

Ancak bu ızgaralar bir eğri içermez:

....  .XX.  ...X  XX..  ....  X.X.
....  X..X  ..XX  XX..  .X.X  .X..
....  .XX.  .X..  ....  ...X  X.X.

Komşu tüm Xs çiftleri arasındaki mesafeleri toplayarak bir eğrinin uzunluğunu bulabiliriz :

  • İki dikey komşu Xs arasındaki mesafe 1 birimdir.

    XX
    X
    X
  • Çapraz olarak komşu iki Xs arasındaki mesafe √2 birimdir.

    X.
    .X
    .X
    X.

Örneğin, ızgaradaki eğrinin uzunluğu

XXX.
...X
..X.

olarak görselleştirilebilir

uzunluk örneği

yani 1 + 1 + √2 + √2 = 4.828427 olduğunu görebiliriz ...

Tek bir eğrinin uzunluğu Xsıfırdır.

Izgara bir eğri oluşturmadığında uzunluğu iyi tanımlanmamıştır.

Meydan okuma

XS ve .s metninden oluşan bir ızgara göz önüne alındığında , içerdiği eğrinin uzunluğunu çıktılar -1veya Nullızgarada eğri olmadığını belirtmek için veya gibi bir şey çıktılar .

Giriş için istenirse Xve dışında başka karakterler kullanabilirsiniz ve .gerekirse H ve W giriş olarak alınabilir. Dize yerine 1s ve 0s ile dolu iç içe liste veya matris olarak giriş de iyidir.

Eğri uzunluğu için bir şamandıra veya alternatif olarak iki A ve B tamsayısı çıktısı alabilirsiniz length = A + B*√2.

Bayt cinsinden en kısa kod kazanır.

Test Durumları

XXX.
...X
..X.
2 + 2*√2 = 4.828427...

....X....
.X.X.X.X.
X..X..X.X
.XX.....X
3 + 8*√2 = 14.313708...

....
....
..X.
0 + 0*√2 = 0

.X..
X..X
.XX.
1 + 3*√2 = 5.242640...

....
..X.
.X..
0 + 1*√2 = 1.414213...

....
XX..
....
1 + 0*√2 = 1

.X.X
X.X.
....
0 + 3*√2 = 4.242640...

....
....
....
....
-1

.XX.
X..X
.XX.
-1

...X
..XX
.X..
-1

....
.X.X
...X
-1

X.X.
.X..
X.X.
-1

Çözücünün eğrisi olmayan ızgaralar için çıktı biçimini seçmesine izin vermenizi öneririm (herhangi bir m için m + n * sqrt (2) biçiminde olmayan herhangi bir tutarlı değer, n≥0).
Greg Martin

@Greg Kulağa hoş geliyor. Bitti
Calvin'in Hobileri

[x.x,...,.x.]geçerli bir eğri değil, değil mi?
Sihirli Ahtapot Urn

@carusocomputing correct
Calvin'in Hobileri

Yanıtlar:


3

MATL , 52 51 bayt

t2Y6~Z+*ssGt3Y6Z+*tt1=z2=wssGzqE=*Gz1=+?}_q]ssy-h2/

Girdi sıfırlar ve birler matrisidir.

Çıktı Bo zaman A. Eğri olmayanlar negatif verir A.

Çevrimiçi deneyin! Veya tüm test senaryolarını doğrulayın .

açıklama

Eğrinin uzunluğunu hesaplamak için iki 2D kıvrım 1 kullanılır : biri Moore maskeli, diğeri sadece diyagonal komşuları içeren maskeli. Sonuçlar, sırasıyla M ve D olarak gösterilecek olan aynı giriş boyutuna sahip iki matristir . M her nokta için toplam komşu sayısını verirken, D diyagonal komşu sayısını verir.

M ve D' deki sonuçlar , eğriye ait olmayan noktaları atmak için filtrelenmelidir. Ayrıca, 2'ye bölünmelidirler, çünkü "komşu olmak" simetrik bir ilişkidir, bu nedenle eğrideki her nokta iki kez sayılır.

Eğrinin geçerli olup olmadığını belirlemek beklediğimden daha hantaldır. Bunu yapmak için kod üç koşulu test eder:

  1. M cinsinden olanların sayısı eşit 2mi? (Yani, tek bir komşu ile tam olarak iki puan mı?)
  2. Toplam M toplamı , giriş eğrisi sürelerindeki 2eksi sayı eksi eşit 2mi? (Koşul 1 ile birlikte, bu, M dışındaki sıfır dışındaki değerlerin ikisi hariç eşit olup olmadığını test eder 2)
  3. Giriş eğrisi tek bir nokta içeriyor mu?

Eğri, koşullar 1 ve 2 doğruysa veya koşul 3 doğruysa geçerlidir.

t       % Implicit input matrix of zeros and ones. Duplicate
2Y6~    % Push [1 0 1; 0 0 0; 1 0 1]
Z+      % 2D convolution, keeping size
*       % Multiply to zero out results for non-curve points. Gives matrix D
ss      % Sum of matrix D
Gt      % Push input again wtice
3Y6     % Push [1 1 1; 1 0 1; 1 1 1]
Z+      % 2D convolution, keeping size
*       % Multiply to zero out results for non-curve points. Gives matrix M
tt      % Duplicate twice
1=z     % Number of ones
2=      % Does it equal 2? This is condition 1
wss     % Swap. Sum of matrix
G       % Push input again
zqE     % Number of nonzeros values minus 1, and then multiplied by 2
=       % Are they equal? This is condition 2
*       % Multiply. This is a logical AND of conditions 1 and 2
G       % Push input again
z1=     % Does it contain exactly one nonzero value? This is condition 3
+       % Add. This is a logical OR with condition 3
?}      % If result was false
  _q    %   Negate and subtract 1. This makes sure we get a negative value
]       % End
ss      % Sum of matrix M
y       % Duplicate sum of matrix D from below
-       % Subtract
h       % Concatenate horizontally
2/      % Divide by 2. Implicitly display

1 Evrişim başarının anahtarıdır .


1

Python 3 , 316 315 311 bayt

Bunun tüm vakaları kapsadığını düşünüyorum; en azından test senaryoları işe yarıyor.

Ayrıca, muhtemelen kenar vakaların ele alındığı başlangıçta golf oynamak için hala çok şey var.

def f(d,R,C):
 s=sum;d=[0]*(C+2),*[[0,*r,0]for r in d],[0]*(C+2);o=-1,0,1;k=[[[(1,0),(0,1)][i*j]for i in o for j in o if d[r+i][c+j]and i|j]for c in range(1,-~C)for r in range(1,-~R)if d[r][c]];w=[x/2for x in map(s,zip(*s(k,[])))]or[0,0];print([w,-1][s(w)!=s([s(z)for z in d])-1or[len(t)for t in k].count(1)>2])

Çevrimiçi deneyin!

Nasıl çalışır:

  1. d,R,C 1. eğri olarak 1 ve arka plan olarak 0, 2. satır ve sütun sayısı olan listelerin bir listesi
  2. d2d dizisinin kenarı hakkında endişelenmemize gerek kalmadan önce ve sonra 0'lık bir satır ve önce ve sonra 0'lık bir sütun ekleyin .
  3. 2d dizisindeki her 1 için mahalleyi 1'ler için tarayın ve ilişki çaprazsa listeye (1,0) ekleyin, yoksa (0,1) ekleyin
  4. Tüm kümeleri toplayın, böylece (n, m) sırasıyla diyagonal ve diyagonal olmayan komşuların sayısını temsil eder
  5. İlişki sayısının tam olarak 1'in eksi bir sayısı olup olmadığını kontrol edin; değilse, bir eğri değil.

Kayıp bir vakayı işaret ettiği için @Helka Homba'ya teşekkürler. Golf ipuçları için @TuukkaX ve @Trelzevir'e teşekkürler.


Görünüşe göre d=[[1,0,1],[0,1,0],[1,0,1]]burada başarısız olacak (testcase eklendi).
Calvin'in Hobileri

@HelkaHomba Haklısın, ben bunu denetledim. Düzeltildi (şimdi maalesef daha fazla bayt ile).
Nil

1
s=sum4 bayt kaydeder.
Trelzevir

0

Mathematica, 153150 bayt

Switch[Sort[Join@@BlockMap[If[#[[2,2]]<1,Nothing,Tr[Tr/@#]]&,#~ArrayPad~1,{3,3},1]],{1},0,{2,2,3...},1/.#~ComponentMeasurements~"PolygonalLength",_,]&

2D dizisini alır, 0s için .s ve 1s için Xs. NullEğri olmayanlar için çıktılar .

1/.#~ComponentMeasurements~"PolygonalLength"&

Mathematica'da bunun için 45 baytlık bir yerleşik vardır, ancak eğri olmayanlar için bazı sayılar ve giriş için 1 / sqrt (2) verir {{1}}. Bu maliyeti 105 bayt düzeltmek (golf olabilir?).

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.