的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
s 的数目,因为true
计数为1
,false
计数为0
。