JavaScript (ES7), 121 bis 117 Byte
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
Wow. Das hat Spaß gemacht. Ich skizzierte eine Antwortidee, als diese Herausforderung zum ersten Mal herauskam, aber sie war über 150 Byte lang und ich wollte mich nicht anstrengen, um Golf zu spielen. Ich bin gestern auf diese Idee in meinem Notizbuch gestoßen und habe beschlossen, nicht aufzuhören, darüber nachzudenken, bis ich sie vollständig ausprobiert habe. Am Ende habe ich zwei völlig neue Algorithmen geschrieben, von denen der erste einige Bytes kürzer ausfiel, nachdem ich mit Tonnen von Bit-Hacking etwa 25 Bytes abgelegt hatte.
Wie es funktioniert
Zuerst setzen wir Variablen a
und b
bis 0
. a
ist ein 4-Bit-Binärarray, in dem sich Klammernpaare befinden, und b
ist ein 16-Bit-Binärarray, in dem Klammernpaare miteinander verknüpft sind.
Als nächstes durchlaufen wir jedes Zeichen c
in x
und jedes Zeichen d
in '0123'
. Zuerst bestimmen wir, um welche Art von Klammer es sich c
handelt e=c.charCodeAt()/26-1|0
. Die Dezimalzeichencodes der einzelnen Klammertypen lauten wie folgt:
() => 40,41
<> => 60,62
[] => 91,93
{} => 123,125
Durch Teilen durch 26, Subtrahieren von 1 und Flooring ordnen wir diese jeweils 0, 1, 2 und 3 zu.
Als nächstes prüfen wir, ob diese Zahl dem aktuellen Wert von entspricht d
. Wenn dies der Fall ist, geben wir entweder den d
Typ der dritten Klammer ein oder verlassen ihn , und klappen das d
dritte Bit a
mit ein a^=1<<d
. Wenn es nicht, aber wir sind in der d
th Haltewinkelart, müssen wir den Flip - e
te Bit in dem d
th 4-Bit - Abschnitt b
. Das geht so:
b^=(a>>d&1)<<d*4+e
(a>>d&1)
Gibt das d
th-Bit in zurück a
. Befinden wir uns innerhalb des d
Klammer-Typs, wird 1 zurückgegeben. Andernfalls wird 0 zurückgegeben. Als Nächstes verschieben wir dies um d*4+e
Bits nach links und XOR b
um das Ergebnis. Wenn wir uns innerhalb des d
Typs der dritten Klammer befinden, ist diese XOR-Verknüpfung das dritte d*4+e
Bit von b
; sonst macht es nichts.
Enthält am Ende der gesamten Schleife b
eine Anzahl von 1-Bit, die dem doppelten Wert des gewünschten Rückgabewerts entspricht. Aber wir müssen noch herausfinden, wie viele Bits das sind. Hier kommt die Unterfunktion ins f
Spiel:
f=y=>y&&y%2+f(y>>1)
Wenn y
0 ist, gibt dies einfach 0 zurück. Andernfalls nimmt es das letzte Bit von y
mit y%2
und fügt dann das Ergebnis der y
erneuten Ausführung aller bis auf das letzte Bit durch die Funktion hinzu. Beispielsweise:
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
Wir b
durchlaufen diese Funktion und teilen das Ergebnis durch 2, und es gibt unsere Antwort.