JavaScript (ES7), 121 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. Itu tadi menyenangkan. Saya membuat sketsa ide jawaban ketika tantangan ini pertama kali keluar, tetapi panjangnya lebih dari 150 byte dan saya tidak ingin melakukan upaya untuk golf itu. Saya menemukan ide ini di notebook saya kemarin dan memutuskan saya tidak akan berhenti memikirkannya sampai saya benar-benar bermain golf. Saya akhirnya menulis dua algoritma yang sama sekali baru, yang pertama berakhir dengan beberapa byte lebih pendek setelah bermain golf sekitar 25 byte dengan banyak bit-hacking.
Bagaimana itu bekerja
Pertama kita atur variabel a
dan b
ke 0
. a
adalah array biner 4-bit di mana pasangan braket saat ini kita berada di dalam, danb
merupakan array biner 16-bit di mana pasangan braket dihubungkan bersama.
Selanjutnya, kita mengulang setiap karakter c
di x
, dan setiap karakter d
di '0123'
. Pertama kita menentukan jenis bracket c
adalah dengan e=c.charCodeAt()/26-1|0
. Kode karakter desimal masing-masing jenis braket adalah sebagai berikut:
() => 40,41
<> => 60,62
[] => 91,93
{} => 123,125
Dengan membaginya dengan 26, mengurangi 1, dan lantai, kami memetakan ini masing-masing menjadi 0, 1, 2, dan 3.
Selanjutnya kita periksa apakah angka ini sama dengan nilai saat ini d
. Jika ya, kita baik masuk atau keluar d
th jenis bracket, jadi kami membalik d
bit th di a
dengan a^=1<<d
. Jika tidak, tetapi kita berada di dalam d
tipe braket th, kita perlu membalik e
bit d
ke-4 di bagian 4-bit b
. Ini dilakukan seperti ini:
b^=(a>>d&1)<<d*4+e
(a>>d&1)
Mengembalikan d
bit ke dalam a
. Jika kita berada di dalam d
tipe braket th, ini mengembalikan 1; jika tidak, ia mengembalikan 0. Selanjutnya, kita menggeser ini ditinggalkan oleh d*4+e
bit, dan XOR b
oleh hasilnya. Jika kita berada di dalam d
tipe braket th, ini XOR d*4+e
bit th b
; jika tidak, ia tidak melakukan apa-apa.
Di akhir semua perulangan, b
akan berisi sejumlah 1-bit sama dengan dua kali nilai pengembalian yang diinginkan. Tetapi kita masih perlu mencari tahu berapa banyak bit ini. Di situlah sub-fungsi f
masuk:
f=y=>y&&y%2+f(y>>1)
Jika y
0, ini hanya mengembalikan 0. Jika tidak, dibutuhkan bit terakhir y
dengan y%2
, lalu menambahkan hasil menjalankan semua kecuali bit terakhir y
melalui fungsi lagi. Sebagai contoh:
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
Kami menjalankan b
melalui fungsi ini dan membagi hasilnya dengan 2, dan ada jawaban kami.