Javascript (ES7), 121 117 bytes
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
Guau. Eso fue divertido. Esbocé una idea de respuesta cuando apareció este desafío por primera vez, pero tenía más de 150 bytes de longitud y no quería esforzarme por jugarlo. Me encontré con esta idea en mi cuaderno ayer y decidí que no dejaría de pensar en ello hasta que lo hubiera jugado por completo. Terminé escribiendo dos algoritmos completamente nuevos, el primero de los cuales terminó varios bytes más cortos después de jugar alrededor de 25 bytes con toneladas de pirateo de bits.
Cómo funciona
Primero establecemos variables ay bto 0. aes una matriz binaria de 4 bits de los pares de paréntesis en los que estamos actualmente, y bes una matriz binaria de 16 bits cuyos pares de paréntesis están unidos entre sí.
A continuación, recorrer cada carácter cen x, y cada carbón den '0123'. Primero determinamos con qué tipo de soporte cestá e=c.charCodeAt()/26-1|0. Los códigos de caracteres decimales de cada tipo de paréntesis son los siguientes:
() => 40,41
<> => 60,62
[] => 91,93
{} => 123,125
Al dividir por 26, restar 1 y piso, los asignamos a 0, 1, 2 y 3, respectivamente.
Luego verificamos si este número es igual al valor actual de d. Si es así, estamos entrando o saliendo del dtipo de soporte th, por lo que cambiamos el dbit th acon a^=1<<d. Si no lo es, sino que están dentro del dtipo de soporte XX, tenemos que darle la vuelta al eésimo bit en la dsección de 4 bits º de b. Esto se hace así:
b^=(a>>d&1)<<d*4+e
(a>>d&1)Devuelve el dbit de entrada a. Si estamos dentro del dtipo de soporte, esto devuelve 1; de lo contrario, devuelve 0. A continuación, desplazamos esto a la izquierda por d*4+ebits, y XOR bpor el resultado. Si estamos dentro del dtipo de corchete, este XOR es el d*4+ebit de b; de lo contrario, no hace nada.
Al final de todo el bucle, bcontendrá un número de 1 bits igual al doble del valor de retorno deseado. Pero aún necesitamos averiguar cuántos bits es esto. Ahí es donde fentra la subfunción :
f=y=>y&&y%2+f(y>>1)
Si yes 0, esto simplemente devuelve 0. De lo contrario, toma el último bit de ywith y%2, luego agrega el resultado de ejecutar todo excepto el último bit a ytravés de la función nuevamente. Por ejemplo:
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
Realizamos besta función y dividimos el resultado entre 2, y ahí está nuestra respuesta.