JavaScript (ES7), 121 117 bayt
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
Vay. Bu eğlenceliydi. Bu meydan okuma ilk ortaya çıktığında bir cevap fikri çizdim, ancak 150 bayttan fazlaydı ve golf oynamak için çaba sarf etmek istemedim. Dün bu fikri rastladım ve tamamen golf oynayana kadar düşünmeyi bırakmayacağına karar verdim. İki yeni bit algoritma yazdım, bunlardan ilki, tonlarca bit hackiyle 25 bayt civarında golf oynadıktan sonra birkaç bayt daha kısa oldu.
Nasıl çalışır
İlk önce a
ve b
ile değişkenleri belirledik 0
. a
şu anda içinde bulunduğumuz parantez çiftlerinin bulunduğu 4 bitlik bir ikili dizidir veb
parantez çiftlerinin bulunduğu 4 bitlik bir ikili dizi ve parantez çiftlerinin birbirine bağlandığı 16 bitlik bir ikili dizidir.
Daha sonra, c
içindeki her karakterin içinde x
ve her karakterin d
içinde dönüyoruz '0123'
. İlk önce ne tür bir braketin c
olduğunu belirleriz e=c.charCodeAt()/26-1|0
. Her ayraç türünün ondalık karakter kodları aşağıdaki gibidir:
() => 40,41
<> => 60,62
[] => 91,93
{} => 123,125
26'ya bölerek, 1'i çıkararak ve döşemeyi sıralayarak bunları sırasıyla 0, 1, 2 ve 3 ile eşleştiririz.
Daha sonra bu sayının şu anki değere eşit olup olmadığını kontrol edeceğiz d
. Eğer durum bu ise, biz ya giriyoruz ya çıkarken d
biz çevirmek böylece, inci braket tipi d
de inci biti a
ile a^=1<<d
. O değil, ama biz ise şunlardır içeride d
inci braket tipi, biz çevirmek gerekir e
içinde inci biti d
th 4 bitlik bölüm b
. Bu böyle yapılır:
b^=(a>>d&1)<<d*4+e
(a>>d&1)
d
Th bitini döndürür a
. Eğer d
parantez tipinin içindeysek , bu 1 döndürür; aksi takdirde, 0 döndürür. Sonra, bu sola d*4+e
bitler, XOR b
sonuçla döneriz . Eğer d
parantez tipinin içindeysek , bu XOR d*4+e
th's bit b
; Aksi takdirde, hiçbir şey yapmaz.
Tüm döngünün sonunda b
, istenen dönüş değerinin iki katına eşit bir miktar 1 bit içerecektir. Fakat bunun kaç bit olduğunu bulmamız gerekiyor. Alt fonksiyonun girdiği f
yer:
f=y=>y&&y%2+f(y>>1)
Eğer y
0'dır, bu basitçe 0. Aksi takdirde, son bit alır döndürür y
ile y%2
daha sonra tüm ama son bit çalışan sonucunu ekler, y
tekrar işlevi aracılığıyla. Örneğin:
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
Biz koşmak b
bu işlev sayesinde sonucu 2 ile bölmek ve cevabımız yoktur.