Bir Mayın Tarlası panosunu doğrulama


33

Amacınız tamamlanmış bir Mayın Tarlası panosunun geçerli olup olmadığını kontrol etmektir. Bu, her sayının köşegenler de dahil olmak üzere bitişik hücrelerdeki doğru mayın sayısı olduğu anlamına gelir. Tahtanın etrafı sarılmıyor.

Her zamanki gibi bir işlev veya program vermelisiniz ve bayt cinsinden en kısa kodu kazanmalısınız.

Mayın Tarlası'nı oluşturmak , çözmek ve tam olarak uygulamak için geçmiş zorluklara da bakın .

Giriş:

Böyle bir tek dizesi: 02X2 13X2 X211.

  • Mayın Tarlası panosunun satırları boşluklarla ayrılmış olarak verilmiştir. Yani, yukarıdaki 3x4 kurulu temsil eder:

    02X2
    13X2
    X211

  • Her hücre bir karakterdir: Xbir mayın veya bir sayı 0için 8.

  • Tüm satırlar aynı uzunluktadır.

  • En az 3 satır ve 3 sütun var.

  • Giriş bir boşlukla başlamaz veya bitmez, ancak dilerseniz sonunda bir yeni satır ekleyebilirsiniz.

Çıktı:

Tutarlı bir Truthy doğru panoları ve tutarlı bir Falsey yanlış panolarında değer. Tutarlı , tüm Truthy çıkışlarının aynı olduğu ve tüm Falsey çıkışlarının aynı olduğu anlamına gelir.

Test durumları

Her satır ayrı bir test durumudur.

True:

02X2 13X2 X211
XXXX XXXX XXXX XXXX
XX4X2 5X6X4 XX6XX 4XX54 2X4XX

False:

02X2 13X2 X212
XXXX XXXX X7XX XXXX
XX5X2 5X6X4 XX6XX 4XX54 2X5XX

Muhtemelen tutarlı sahte çıktının tutarlı gerçek çıktıdan farklı olması gerektiğini belirtmelisiniz ;-)
John Dvorak

@JanDvorak Bu, sırasıyla Truthy ve Falsey olmaları nedeniyle ima edilmelidir.
xnor

Pek sayılmaz. "truthy" ve "falsy" tanımlamamıza izin verdiğiniz iki etikettir. Kısıtlamalar göremiyorum, aslında kullandığımız dilde sıra dışı ya da sahte. Farklı olmalarını gerektiren tek kelime "belirten" fiildir. Spesifik olarak sayıldığından emin değilim (yine de standart bir boşluk olarak yasaktır).
John Dvorak

4
@JanDvorak 'truthy' ve 'falsy', genel olarak, genel olarak, yazarken yazarken doğru veya yanlış olarak değerlendirilen şeyleri (zorunlu olarak değil) açıklamak için yanlış kullanılmazsam, genel terimlerdir. Örneğin, 0 genellikle sahtedir ve 1 genellikle truthy'dir.
KSab,

1
@JanDvorak Hayır, Truthy / Falsey'in doğru / yanlış eşleşmesi gerekiyor.
xnor

Yanıtlar:


11

Python 2, 132 129 128

def f(s):w=s.find(' ');E=dict(enumerate(s));return all(E[i]in' X'+`sum(E.get(i+d/3*~w+d%3+w,5)>'O'for d in range(9))`for i in E)

enumerateBir golfde kullandım ... hatta rangeaynı programda başka yerlerde de kullandım . Açıkçası burada bir şeyler yanlış.

Düzenleme: Üzerinde yineleme dict(enumerate(s)) yerineenumerate(s) , enumerateiki kez çağrılması gerekmez.


Ne akıllıca bir kullanım ~! Ve sınır dışı indekslemeyi doğru yapmak için sözlükler.
xnor

@xnor ~Operatör hakkındaki yorumunuz ironik bir şekilde iki kez kullandığımı, hiçbir zaman sebepsizin kullandığımı, sadece bir kez kullanmanın aynı şeyi yapabileceğini fark etti. Sözlük kısmının komik olduğunu düşünmüştüm, teşekkürler.
feersum

9

Pyth, 43

Jhxzd!f-@zT+" X"`sm/:+*JNztd+d2\Xm+T*kJU3Uz

Dene Burada .

Açıklama:

  • Jhxzd: Bu, + 1 girişindeki ilk boşluğun yeri. (z girişte, dboşluktur.) Girişteki karttaki dikey olarak bitişik hücreler arasındaki ayrımdır.
  • !f: Bu mantıklı değil (! bir filtrenin ) )f )True ifadesi olup, yalnızca dizinin her öğesi için ifadenin yanlış olması durumunda olacaktır .
  • -@zT: Lokasyondaki karakteri al T (lambda değişkeni) alın ve aşağıdakilerin göründüğünü kaldırın: (Karakter kaldırılmazsa bu doğrudur ve öyleyse sahte olur.
  • +" X": Boşluğu kaldır, X ve
  • `: Repr
  • sm: haritanın toplamı
  • / \X: içindeki "X" sayısı
  • :+*JNz: Girilen dilimin ön eki J sahte karakterlerle
  • td+d2: D-1'den d + 2'ye.
  • m+T*kJU3: D için [T, T + J, T + 2 * J].
  • UzT girişi için range(len(input)).

7
Downvoters: Neden downvotes?
isaacg

7

APL (NARS2000) (74)

{~0∊(G>9)∨G=(⍴G)↑{+/∊9<⍵∘⌷¨G∘.⊖(G←2-⍳3)∘.⌽⊂Z}¨⍳⍴Z←G↑⍨2+⍴G←¯1+⎕D⍳⊃⍵⊂⍨⍵≠' '}

Ayrıca eğer ⎕MLayarlanırsa Dyalog APL'de çalışır 3.

Açıklama:

  • ⊃⍵⊂⍨⍵≠' ': boşluklara bölün ve listeleri bir matris oluşturmak için kullanın.
  • G←¯1+⎕D⍳: ⎕Dher değer için dizini bulun, 1'i çıkarın ve bunu saklayın G. ( ⎕Drakamları içerir, herhangi bir rakam olmayanlar10 ).
  • Z←G↑⍨2+⍴G: sarmalama ile başa çıkmak için matrisin kenarına iki satır ve sıfır sütunları ekleyin
  • {... }¨⍳⍴Z: içindeki her konum içinZ , bu pozisyondaki Moore mahallesindeki bomba miktarını bulun:
    • G∘.⊖(G←2-⍳3)∘.⌽⊂Z: Zsola, sağa, yukarı, aşağı, sola, sağa, sola ve sağa döndürün .
    • ⍵∘⌷¨: Bunların her biri için, bu döndürülmüş matrislerin her birinde öğeyi bulun.
    • +/∊9<: kaç elementin 9'dan daha yüksek olduğunu sayın (bu bombaların miktarıdır).
  • (⍴G)↑: eklenen sıfır satırlarını tekrar kaldırın,
  • G=: her bir elemanın Go pozisyonu çevreleyen bomba miktarına eşit olup olmadığını kontrol edin (bu tüm bombalamayan kareler için geçerli olmalı),
  • (G>9)∨: ve içindeki öğelerin Gdeğerinden yüksek olup olmadığını kontrol edin9 (bunlar bombalardır).
  • ~0∊: 1Eğer sonuç matrisinde sıfır yoksa (= tüm kareler bomba ya da doğru sayıdır) ve 0eğer varsa döndür.

Bayt veya karakter saydınız mı? Bayt saymalısınız.
Tim S.

5
@TimS .: 1 bayt APL kodlaması var, bir tane var .
marinus

5

C #, 321 320 305

bool s(string B){var L=B.Split(' ').Select(s=>' '+s+' ').ToList();var b=new string(' ',L[0].Length);L.Insert(0,b);L.Add(b);Func<int,int,IEnumerable<int>>E=Enumerable.Range;return E(1,b.Length-2).All(x=>E(1,L.Count-2).All(y=>L[y][x]=='X'||L[y][x]-'0'==E(x-1,3).Sum(X=>E(y-1,3).Sum(Y=>L[Y][X]=='X'?1:0))));}

Öncelikle bir şeyi golf oynamaya çalışın ve C # 'nın ideal dil olmadığını biliyorum.

Umarım bir örnek yöntemi yazma izin verilir, aksi halde için 7 karakter ekleyin static.

Aralıklı:

bool s(string B) {
    var L = B.Split(' ').Select(s => ' ' + s + ' ').ToList();
    var b = new string(' ', L[0].Length);
    L.Insert(0, b);
    L.Add(b);
    Func<int, int, IEnumerable<int>> E = Enumerable.Range;
    return E(1, b.Length - 2).All(x =>
        E(1, L.Count - 2).All(y =>
            L[y][x] == 'X' ||
            L[y][x] - '0' == E(x - 1, 3).Sum(X =>
                E(y - 1, 3).Sum(Y =>
                  L[Y][X] == 'X' ? 1 : 0))));
}

Linq kullanmak döngülere kıyasla biraz yer kazandırır, ancak hata ayıklaması daha zordur.

char => intÇıkarma yoluyla dönüştürme gibi birkaç şey öğrendim '0'.

Tahtayı boşluklarla doldurmak daha kolay gözüküyordu, böylece üzerine tekrar yazmak daha kolay olurdu.


1
Değiştirmek yapamam -'0'ile -48. Benim için çalışır ve çeşitli 'X' ve '' için birkaç bayt kazandırır
Roman Gräf

5

Python 2, 121

def f(B):n=B.find(' ')+1;R=range(len(B));print all(B[I]in' X'+`sum(2>I%n-i%n>-2<I/n-i/n<2<B[i]>'W'for i in R)`for I in R)

Bu, büyük ölçüde feersum'un cevabından ilham alıyor . Günün sırası aşırı derecede fazla: hücrenin 9 komşusundaki mayınları kontrol etmek yerine, komşu bir mayın olup olmadığını görmek için her bir hücreyi kontrol edin.

İki hücrenin komşu olup olmadığını, hücrelerin satır ve sütun farklılıklarının 2>r>-2<c<2nerede rve nerede olduğunu kontrol cediyoruz {r,c}<{-1,0,1}. Bu koordinatlar, hücre endekslerin hesaplanır Ive işekilde c=I%n-i%nve r=I/n-i/n. Doğrudan dizeye endekslemek ve satırları ve sütunları çıkarmak, bir liste listesi gibi 2B nesneye dönüştürmekten daha etkilidir. Mayın kontrolü, B[i]>'W'burada eşdeğerdir B[i]=='X'.

Kullanımı enumerate, range(len(B))içinden iç içe iki döngüyü desteklemeyen bir yineleyici nesnesini döndürmesi dışında , çirkin üzerine iki karakter kaydederdi .


Bence negatif bir modül n için çalışmalı; o zaman kullanabilirsin ~B.find.
14'te

@ feersum Maalesef bu /durum olumsuzlaştı , çünkü olumsuzları da aşağı yuvarlıyor .
xnor

4

Python 2, 140

s=input();w=s.index(' ')+1
print all(c in'X 'or(int(c)==sum(s[max(0,a-1):max(0,a+2)].count('X')for a in[i-w,i,i+w]))for i,c in enumerate(s))

4

JavaScript (ES6), 135 133 125 122

f=s=>s.split(" ")[e="every"]((l,i,a)=>[...l][e]((c,j)=>!(-[-1,0,k=1][e]((y,m,q)=>q[e](x=>k+=(a[i+y]||0)[j+x]=="X"))-c+k)))

İşleve bir dize olarak girdi sağlayın:

f("XX4X2 5X6X4 XX6XX 4XX54 2X4XX");

Bir açıklama için aşağıdaki eski sürüme bakın. Yeni sürüm, fordöngüleri everyçağrılarla değiştirir ve e="every"yapılacak değişkeni kullanır.someArray[e](...) yerine .someArray.every(...) .

Ayrıca, sayaç kşimdi indekslenir, 1böylece döngünün çalışmaya k+=...devam etmesi için ifadenin her zaman kaba olması sağlanır every. Bu fazlalığı , işlemin döndürdüğü sonucu (sayısal olarak zorlayan ) 1çıkartarak ortadan kaldırırız .true1every[-1,0,k=1][e](...)


Eski versiyon:

f=s=>s.split(" ").every((l,i,a)=>[...l].every((c,j)=>{q=[-1,k=0,1];for(y of q)for(x of q)k+=(a[i+y]||0)[j+x]=="X";return c=="X"||k==c}))

Boşluk ve yorum içeren kod:

f=s=>s.split(" ")                 // split on spaces
      .every((l,i,a)=>             // for every line
                                   //     l: line string, i: line number, a: whole array
          [...l].every((c,j)=>{    // for every character
                                   //     c: character, j: index in string
              q=[-1,k=0,1];        // define counter k=0 and q=[-1,0,1]
              for(y of q)          // use q to loop adjacent spaces
                  for(x of q)

                      k+=              // add the following boolean to k:

                          (a[i+y]      //   from line number i+y...
                                 ||0)  //   (or a dummy zero, to prevent lookups on undefined)
                          [j+x]        //   ...get index j+x from the above value...
                                =="X"; //   ...and compare it to "X"

              return !(k-c)     // after the loop, this character passed if
                                // the char equals the number of counted X's (so k-c is 0)
                                // or it is an X itself (so `k-c` is NaN)
          })
      )

JavaScript everydizi yöntemi bir geri arama alır ve geri aramayı dizinin her öğesine uygular. Herhangi bir geri arama bir falsey değeri verirse, everygeri aramafalse .

JS'deki Boolean'ler bir ilavenin parçası olduğunda 1 veya 0'a zorlanır. Her çevreleyen alan için, değerini karşılaştırmanın Boole sonucunu "ekleriz" Xve sonra bu değeri kifadedeki sayaca ekleriz k += (... == "X"). Bu nedenle, kçevreleyen sayının sayısını içerir X, çünkü truesayılır 1ve falsesayılır 0.


c=="X"Denemek yerine, !c/1sizi büyük miktarda boğmaca bayttan kurtarır! Başarısız olursa, dene !!c/1. Muhakeme yani 'X'/1 => NaN, ve NaNfalsie olduğunu. Sen kontrol c=='X', neden değilse kontrol etmeye false?
Ismael Miguel,

@IsmaelMiguel Bu (!c)/1ne yazık ki; 2 olan parantezlerin olması gerekirdi !(c/1). Ayrıca 0/1falsey, bu nedenle geçersiz girdi " 0X" yanlış sonuç verecek true. Hala sıfıra saygı gösterirken yapabileceğim en iyi şey, iki koşulu olumsuz bir cümleyle birleştirmektir !(+c+1&&k-c), ancak bu zaten sahip olduğum uzunluk ile aynıdır.
apsillers

Gerçi beni düşünmeye almak için @IsmaelMiguel teşekkürler - fark ettik !(k-1-c)testler her iki durum, çünkü eğer kmaçlar c(eksi 1 ofset), sonra olumsuzluk yapar 0doğrudur ve eğer cbir sayı elde ederiz değildir NaNve olumsuzluk aynı zamanda true.
apsillers

Gerçekten açtın! İlk koddan beri 10 byte yedin! Karşılaştığınız çözümü gerçekten seviyorum. Çözümünüz için +1!
Ismael Miguel,

3

CJam, 70 65 63 bayt

1l_S#):L)S*+:Q{Ii33/2%[0~1LL)L(L~)L~_))]W):Wf+Qf='X/,(scI==&}fI

Bu çok golf oynayabilir.

1Geçerli bir kurul ve 0geçersiz bir kurul için verir .

Test durumları

{-1:W;
1l_S#):L)S*+:Q{Ii33/2%[0~1LL)L(L~)L~_))]W):Wf+Qf='X/,(scI==&}fI
}6*]N*

Giriş

02X2 13X2 X211
XXXX XXXX XXXX XXXX
XX4X2 5X6X4 XX6XX 4XX54 2X4XX
02X2 13X2 X212
XXXX XXXX X7XX XXXX
XX5X2 5X6X4 XX6XX 4XX54 2X5XX

Çıktı

1
1
1
0
0
0

Burada çevrimiçi deneyin


3

JavaScript (ES6) 98

Kullanılması Bazı dize her karakter için bir işlevi uygulamak için.
İşlev döndürür

  • boşsa false
  • Eğer 'X' ise NaN (art arda 'X' gibi sayısal olmayan bir karakterden değerleri çıkarmak NaN verir)
  • Eğer doğru sayıda 'X' sayısının 'X', '0' olmayan sayıları varsa sayısal bir değer.
    İç kontrol sadece Each'dan daha kısa olduğundan harita kullanılarak yapılır.

bazıları , ilk kontrol değerinde (bu durumda, sıfır olmayan) doğru bir kontrolün başarısız olduğu anlamına gelir. Sonuç, daha tanınabilir bir doğru / yanlış vermeyi reddetti.

F=v=>![...v].some(
  (x,p)=>x!=' '&&[1,-1,l=v.search(' '),-l,++l,-l,++l,-l].map(q=>x-=v[p+q]=='X')|x
)

FireFox / FireBug konsolunda test edin

;["02X2 13X2 X212","XXXX XXXX X7XX XXXX","XX5X2 5X6X4 XX6XX 4XX54 2X5XX"
,"02X2 13X2 X211","XXXX XXXX XXXX XXXX","XX4X2 5X6X4 XX6XX 4XX54 2X4XX","111 1X1 111"]
.forEach(t => console.log(t, F(t)))

Çıktı

02X2 13X2 X212 false
XXXX XXXX X7XX XXXX false
XX5X2 5X6X4 XX6XX 4XX54 2X5XX false
02X2 13X2 X211 true
XXXX XXXX XXXX XXXX true
XX4X2 5X6X4 XX6XX 4XX54 2X4XX true
111 1X1 111 true

1

R, 156 karakter

a=b=do.call(rbind,strsplit(scan(,""),""));for(i in 1:nrow(a))for(j in 1:ncol(a))b[i,j]=sum(a[abs(i-row(a))<2&abs(j-col(a))<2]=="X");v=a!="X";all(b[v]==a[v])

Okunabilirlik için girintiler, boşluklar ve satır kesmeleriyle:

a = b = do.call(rbind,strsplit(scan(,""),"")) #Reads stdin and turn into a matrix
for(i in 1:nrow(a)) #Ugly, ugly loop
    for(j in 1:ncol(a))
        b[i,j] = sum(a[abs(i-row(a))<2 & abs(j-col(a))<2]=="X")
v = a!="X"
all(b[v]==a[v])

Örnekler:

> a=b=do.call(rbind,strsplit(scan(,""),""));for(i in 1:nrow(a))for(j in 1:ncol(a))b[i,j]=sum(a[abs(i-row(a))<2&abs(j-col(a))<2]=="X");v=a!="X";all(b[v]==a[v])
1: XX4X2 5X6X4 XX6XX 4XX54 2X4XX
6: 
Read 5 items
[1] TRUE
> a=b=do.call(rbind,strsplit(scan(,""),""));for(i in 1:nrow(a))for(j in 1:ncol(a))b[i,j]=sum(a[abs(i-row(a))<2&abs(j-col(a))<2]=="X");v=a!="X";all(b[v]==a[v])
1: XXXX XXXX XXXX XXXX
5: 
Read 4 items
[1] TRUE
> a=b=do.call(rbind,strsplit(scan(,""),""));for(i in 1:nrow(a))for(j in 1:ncol(a))b[i,j]=sum(a[abs(i-row(a))<2&abs(j-col(a))<2]=="X");v=a!="X";all(b[v]==a[v])
1: XX5X2 5X6X4 XX6XX 4XX54 2X5XX
6: 
Read 5 items
[1] FALSE
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.