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
インデックスが作成され1
、k+=...
式が常に真実になるようになりましたevery
。操作によって返された結果(数値的に強制する)を1
減算するtrue
ことにより、余分な部分を削除します。1
every
[-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
ため、周囲のの数のカウントを含みます。true
1
false
0