JavaScript (ES7), 121117 octets
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
Sensationnel. C'était amusant. J'ai esquissé une idée de réponse lorsque ce défi est apparu pour la première fois, mais il faisait plus de 150 octets et je ne voulais pas faire l'effort de le jouer au golf. J'ai rencontré cette idée dans mon carnet hier et j'ai décidé de ne pas y penser tant que je ne l'aurais pas entièrement jouée. J'ai fini par écrire deux algorithmes entièrement nouveaux, dont le premier s'est retrouvé plusieurs octets plus court après avoir joué à environ 25 octets avec des tonnes de piratage de bits.
Comment ça marche
Nous avons d' abord définir des variables a
et b
à0
. a
est un tableau binaire 4 bits dont les paires de parenthèses nous sommes actuellement à l'intérieur, etb
est un tableau binaire de 16 bits dont les paires de parenthèses sont liées ensemble.
Ensuite, boucle de nous à travers chaque caractère c
dans x
, et chaque omble chevalier d
dans '0123'
. Nous déterminons d'abord le type de support c
avec e=c.charCodeAt()/26-1|0
. Les codes de caractères décimaux de chaque type de parenthèse sont les suivants:
() => 40,41
<> => 60,62
[] => 91,93
{} => 123,125
En divisant par 26, en soustrayant 1 et le plancher, nous les mappons respectivement à 0, 1, 2 et 3.
Ensuite, nous vérifions si ce nombre est égal à la valeur actuelle de d
. Si c'est le cas, nous entrons ou sortons du d
type de parenthèse e, donc nous retournons le d
bit a
avec a^=1<<d
. Si ce n'est pas le cas, mais que nous sommes à l'intérieur du d
type de parenthèse e, nous devons retourner le e
bit dans la d
section 4 bits de b
. Cela se fait comme suit:
b^=(a>>d&1)<<d*4+e
(a>>d&1)
Renvoie le d
bit e a
. Si nous sommes à l'intérieur du d
type de parenthèse, cela renvoie 1; sinon, elle renvoie 0. Ensuite, nous la décalons à gauche par d*4+e
bits et XOR b
par le résultat. Si nous sommes à l'intérieur du d
type de parenthèse, ce XORs le d*4+e
e bit deb
; sinon, cela ne fait rien.
À la fin de tout le bouclage, b
contiendra un nombre de 1 bits égal au double de la valeur de retour souhaitée. Mais nous devons encore déterminer le nombre de bits. C'est là qu'intervient la sous-fonction f
:
f=y=>y&&y%2+f(y>>1)
Si y
est 0, cela renvoie simplement 0. Sinon, il prend le dernier bit de y
avec y%2
, puis ajoute à nouveau le résultat de l'exécution de tout sauf du dernier bit y
dans la fonction. Par exemple:
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
Nous parcourons b
cette fonction et divisons le résultat par 2, et voici notre réponse.