マインスイーパボードを確認する


33

目標は、完成した掃海艇ボードが有効かどうかを確認することです。これは、各数値が、対角線を含む隣接するセル内の地雷の正しいカウントであることを意味します。ボードはラップアラウンドしません。

通常どおり、関数またはプログラムを指定する必要があり、バイト単位の最短コードが優先されます。

マインスイーパを生成解決、および完全に実装するための過去の課題も参照してください。

入力:

このような単一の文字列:02X2 13X2 X211

  • マインスイーパボードの行は、スペースで区切って指定します。したがって、上記は3x4ボードを表します。

    02X2
    13X2
    X211

  • :各セルは文字であるX鉱山のために、または数0による8

  • すべての行の長さは同じです。

  • 少なくとも3行3列です。

  • 入力はスペースで開始または終了しませんが、必要に応じて改行を最後に含めることができます。

出力:

一貫Truthy正しいボード上、および一貫性のFalseyの間違ったボード上の値。一貫性とは、すべてのTruthy出力が同じで、すべてのFalsey出力が同じであることを意味します。

テストケース

各行は個別のテストケースです。

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

おそらく一貫した偽の出力は一貫した真実の出力とは異なる必要があることを指定する必要があります;
ジョンドヴォルザーク14

@JanDvorakそれは、それらがそれぞれTruthyとFalseyであることによって暗示されるべきです。
xnor 14

あんまり。「真実」と「虚偽」は、2つのラベルであり、定義することができます。私たちが使用している言語では、実際にそれぞれ真実であるか偽であるかの制限はありません。それらを区別する必要がある唯一の単語は、「指示」動詞です。仕様としてカウントされるかどうかはわかりません(ただし、標準の抜け穴として禁止されています)。
ジョンドヴォルザーク14

4
@JanDvorak 'truthy'および 'falsy'は、boolに入力されたときにtrueまたはfalseに評価されるもの(必ずしもboolであるとは限らない)を説明するために基本的に使用されている場合、実際には多少一般的な用語です。たとえば、0は一般に偽であり、1は一般に真実です。
KSab 14

1
@JanDvorakいや、Truthy / Falseyは正しい/間違ったものを一致させる必要があります。
xnor 14

回答:


11

パイソン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)

enumerateはゴルフで使用rangeし、同じプログラムの他の場所で使用しました。ここで明らかに何かが間違っています。

編集:dict(enumerate(s))ではなく反復処理を行うenumerate(s)ため、enumerate2回呼び出す必要はありません。


なんて賢い使い方~だ!そして、範囲外のインデックス作成を正しく機能させる辞書。
xnor 14

@xnor ~演算子についてのあなたのコメントは皮肉なことに私はまったく理由もなく2回それを使用していることに気づきました。1 回だけ使用すると明らかに同じことを達成します。辞書の部分は面白いと思った、ありがとう。
feersum 14

9

Pyth、43

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

ここで試してみてください

説明:

  • Jhxzd:これは、入力の最初のスペース+ 1の位置です(z入力でdはスペースです)。ボード上の垂直方向に隣接するセル間の入力の間隔です。
  • !f:これは!フィルター(f)の論理True否定()であり、シーケンスのすべての要素に対して式が偽である場合にのみ、そうなります。
  • -@zTT入力から位置(ラムダ変数)の文字を取得し、次の外観を削除します(文字が削除されていない場合はこれは真実であり、削除されている場合は偽です。
  • +" X":スペース、X、および
  • `:Repr of
  • sm:マップの合計
  • / \X:「X」のカウント
  • :+*JNzJダミー文字を前に付けた入力のスライス
  • td+d2:d-1からd + 2まで。
  • m+T*kJU3:[T、T + J、T + 2 * J]のdの場合。
  • UzTの場合range(len(input))

7
Downvoters:なぜdownvotesですか?
isaacg 14

7

APL(NARS2000)(74)

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

Dyalog APLでも動作します ⎕ML設定されて3いるます。

説明:

  • ⊃⍵⊂⍨⍵≠' ': スプリット スペースでし、リストを使用してマトリックスを形成します。
  • G←¯1+⎕D⍳⎕D各値のインデックスを見つけ、1を引き、これをに保存しGます。(⎕D数字が含まれ、数字以外はすべて10)。
  • Z←G↑⍨2+⍴G:ラップアラウンドを処理するために、マトリックスの端にゼロの2つの行と列を追加します
  • {... }¨⍳⍴Z:の各位置に対してZ、その位置のムーア周辺の爆弾の量を見つけます。
    • G∘.⊖(G←2-⍳3)∘.⌽⊂ZZ左、右、上、下、左上、右上、左下、右下に回転します。
    • ⍵∘⌷¨:これらのそれぞれについて、これらの回転されたマトリックスのそれぞれで要素を見つける
    • +/∊9<:9を超える要素の数を数えます(これは爆弾の量です)。
  • (⍴G)↑:追加されたゼロの行を再度削除し、
  • G=:の各要素がGその位置を囲む爆弾の量に等しいかどうかを確認します(これはすべての非爆弾の正方形に当てはまります)。
  • (G>9)∨:およびの要素G9(爆弾である)よりも高いかどうかを確認します。
  • ~0∊1結果の行列にゼロが含まれていない場合(=すべての正方形が爆弾または正しい数である0場合)、含まれている場合に返します。

バイトまたは文字をカウントしましたか?バイトを数える必要があります。
ティムS.

5
@TimSは:1バイトのAPLエンコーディングの負荷がありますが、ここでは1です
マリヌス14

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))));}

まず何でもゴルフに挑戦してみて、C#は理想的な言語ではないことを知っています。

インスタンスメソッドの記述が許可されることを望みますstatic。それ以外の場合は、さらに7文字を追加します。

間隔:

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を使用すると、forループに比べてスペースが節約されますが、デバッグが難しくなります。

私はchar => int引き算することによる変換のようなことを学びました'0'

ボードをスペースで埋める方が簡単であるように思えたので、ボードを反復するのは簡単です。


1
あなたは置き換えるだけではできません-'0'-48。私のために
働き

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)

これは、フェールサムの答えに大きく影響を受けています。その日の順序は行き過ぎです。セルの9つの隣人の地雷をチェックするのではなく、すべてのセルを確認して、それが隣の地雷かどうかを確認します。

2つのセルがで隣接しているかどうかをチェックします2>r>-2<c<2。ここでrおよびcは、セルの行と列の違いで、{r,c}<{-1,0,1}です。これらの座標は、セルインデックスIias c=I%n-i%nおよびから計算されr=I/n-i/nます。リストのリストのような2Dオブジェクトに変換するよりも、文字列に直接インデックスを付けて行と列を抽出する方が効率的です。地雷チェックはB[i]>'W'、ここと同等ですB[i]=='X'

を使用して enumerateすると、range(len(B))2つのネストされたループをサポートしないイテレータオブジェクトを返すことを除いて、2つの文字がい上に保存されます。


負の係数はnで機能するはずです。使用できます~B.find
feersum 14

@feersum残念なことに、/ネガも下に丸めるため、それは台無しになります。
xnor 14

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

関数への入力を文字列として提供します。

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

説明については、以下の古いバージョンを参照してください。新しいバージョンでは、forループがevery呼び出しに置き換えられ、代わりに変数e="every"を使用してsomeArray[e](...)someArray.every(...)

また、ループの実行を維持するために、カウンタのkインデックスが作成され1k+=...式が常に真実になるようになりましたevery。操作によって返された結果(数値的に強制する)を1減算するtrueことにより、余分な部分を削除します。1every[-1,0,k=1][e](...)


古いバージョン:

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

スペースとコメントを含むコード:

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 every配列メソッドはコールバックを受け取り、そのコールバックを配列のすべての要素に適用します。コールバックがfalsey値を返す場合、every呼び出しはを返しますfalse

JSのブール値は、追加の一部である場合、1または0に強制されます。周囲のスペースごとに、その値を比較した結果のブール値を「追加」し、その値を式のXカウンターkに追加しますk += (... == "X")。したがって、kはとしてカウントされ、としてカウントされるXため、周囲のの数のカウントを含みます。true1false0


c=="X"tryの代わりに!c/1、膨大な量のバイトのバイトを節約します!失敗した場合は、を試してください!!c/1。推論はそれ'X'/1 => NaNであり、NaN偽りです。もしそうならc=='X'、そうでないかどうかをチェックしてみませんfalseか?
イスマエルミゲル14

@IsmaelMiguelこれはと同じものを評価し(!c)/1ますが、残念ながら助けにはなりません。の括弧が必要です!(c/1)。これに0/1は2の費用がかかります。また、偽であるため、無効な入力 " 0X"は誤った結果になりtrueます。ゼロを尊重しながらできる最善の方法は、2つの条件を組み合わせて、などの否定句にすることですが!(+c+1&&k-c)、それはすでに持っているものと同じ長さです。
アプシラー14

@IsmaelMiguel考えてくれてありがとう- !(k-1-c)両方の条件をテストすることに気付きました。kマッチc(1オフセットを引いた)の場合、否定が0真になりc、数値でない場合はNaN否定が得られるからです。もtrueです。
アプシラー14

あなたは本当にお腹が空いていました!最初のコードから10バイトを食べました!私はあなたが思いついた解決策が本当に好きです。ソリューションの+1!
イスマエルミゲル14

3

CJam、70 65 63バイト

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

これはたくさんゴルフできます。

与える1有効なボード用と0無効ボードのため。

テストケース

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

入力

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

出力

1
1
1
0
0
0

こちらからオンラインでお試しください


3

JavaScript(ES6)98

いくつかを使用し、文字列の各文字に関数を適用します。
関数は戻ります

  • 空白の場合はfalse
  • 「X」の場合はNaN(「X」のような非数値文字から値を繰り返し減算すると、NaNが得られます)
  • adiacent「X」の右の数がある場合、0の数値は、他の非0
    内部チェックを使用して作られているマップを、それはより短いだという理由だけではforEach

いくつかは、最初の真理値(この場合はゼロ以外)でtrueを返し、チェックの失敗を意味します。結果は否定され、より認識可能なtrue / falseが得られます。

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コンソールでテストする

;["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)))

出力

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文字

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

読みやすくするために、インデント、スペース、改行を使用:

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

例:

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