的JavaScript(ES7),121个 117字节
x=>(a=b=0,[for(c of x)for(d of'1234')(e=c.charCodeAt()/26|0)==d?a^=1<<d:b^=(a>>d&1)<<d*4+e],f=y=>y&&y%2+f(y>>1))(b)/2
哇。那很有趣。当这个挑战第一次出现时,我勾勒出一个答案的想法,但是它的长度超过150个字节,我不想花很多精力去打高尔夫球。昨天我在笔记本上遇到了这个想法,并决定在我完全打高尔夫球之前不要停止思考。我最终写出了两种全新的算法,其中第一种在用大量比特攻击击中约25个字节后,缩短了几个字节。
怎么运行的
首先,我们设置变量a
,并b
给0
。a
是我们当前位于其中的括号对的4位二进制数组,并且b
是其中括号对链接在一起的16位二进制数组。
接下来,通过每一个字符,我们可以循环c
的x
,并且每个字符d
中'0123'
。首先,我们确定支架的类型是什么c
是e=c.charCodeAt()/26-1|0
。每种括号类型的十进制字符代码如下:
() => 40,41
<> => 60,62
[] => 91,93
{} => 123,125
通过除以26,减去1和下限,我们将它们分别映射到0、1、2和3。
接下来,我们检查此数字是否等于的当前值d
。如果是,我们要么进入或离开d
第托架的类型,所以我们翻转d
在第i比特a
与a^=1<<d
。如果不是的话,但我们是里面d
次支架类型,我们需要翻转e
个位的d
的第4位的部分b
。这样做是这样的:
b^=(a>>d&1)<<d*4+e
(a>>d&1)
返回中的d
第th位a
。如果我们在d
第一个方括号内,则返回1;否则,返回0。否则,它返回0。接下来,我们将其向左移d*4+e
一位b
,对结果进行XOR 。如果我们在d
第一个括号类型内,则将X的d*4+e
第X 位与XOR进行异或b
。否则,它什么都不做。
在所有循环结束时,b
将包含等于期望返回值两倍的1位数字。但是我们仍然需要弄清楚这是多少位。这就是子功能的所在f
:
f=y=>y&&y%2+f(y>>1)
如果y
为0,则简单地返回0。否则,它y
使用with 的最后一位y%2
,然后y
通过该函数再次添加除最后一位以外的所有内容。例如:
f(y) => y && y%2 + f(y>>1)
f(0b1001101) => 1 + f(0b100110) = 4
f(0b100110) => 0 + f(0b10011) = 3
f(0b10011) => 1 + f(0b1001) = 3
f(0b1001) => 1 + f(0b100) = 2
f(0b100) => 0 + f(0b10) = 1
f(0b10) => 0 + f(0b1) = 1
f(0b1) => 1 + f(0b0) = 1
f(0b0) => 0 = 0
我们运行b
此函数并将结果除以2,我们得到了答案。