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й біт в aс a^=1<<d. Якщо це не так, але ми перебуваємо всередині dтипу дужки, нам потрібно перевернути цей eбіт у d4-бітному розділі b. Це робиться так:
b^=(a>>d&1)<<d*4+e
(a>>d&1)Повертає dбіт у a. Якщо ми знаходимось у dтипі дужок, це повертає 1; в іншому випадку вона повертається 0. Далі, ми пересуваємо цю ліву на d*4+eбіти, а XOR bза результатом. Якщо ми знаходимось у dтипі дужок, цей XOR - це d*4+eбіт b; інакше нічого не робить.
Наприкінці всього циклу bбуде міститися число 1-бітів, що дорівнює подвоєному бажаному поверненому значенню. Але нам ще потрібно розібратися, скільки це біт. Ось де підфункція fнадходить:
f=y=>y&&y%2+f(y>>1)
Якщо y0, це просто повертає 0. В іншому випадку він бере останній біт yз 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, і є наша відповідь.