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バイト以上の長さでした。昨日、ノートブックでこのアイデアに出くわし、完全にゴルフをするまで考えることをやめないと決めました。最終的に2つのまったく新しいアルゴリズムを作成しました。最初のアルゴリズムは、25バイト前後の大量のビットハッキングでゴルフした後、数バイト短くなりました。
使い方
まず、変数を設定するaとbします0。aは、現在内部にあるブラケットペアの4 bビットバイナリ配列であり、ブラケットペアが互いにリンクされている16ビットバイナリ配列です。
次に、各文字を通じて、私たちのループcではx、各文字dで'0123'。最初に、ブラケットのタイプを決定cしe=c.charCodeAt()/26-1|0ます。各ブラケットタイプの10進文字コードは次のとおりです。
() => 40,41
<> => 60,62
[] => 91,93
{} => 123,125
26で除算し、1を減算し、フローリングすることにより、これらをそれぞれ0、1、2、および3にマッピングします。
次に、この数値がの現在の値と等しいかどうかを確認しますd。そうである場合、dthブラケットタイプを入力または終了するため、でdthビットを反転aしa^=1<<dます。それはありませんが、我々は場合はあるの内側d番目のブラケットの種類、我々は反転する必要があるeでビット目dの第4ビットセクションb。これは次のように行われます。
b^=(a>>d&1)<<d*4+e
(a>>d&1)のdthビットを返しますa。dthブラケット型の中にいる場合、これは1を返します。それ以外の場合は、0を返します。次に、d*4+eビットを左にシフトbし、結果をXOR します。dthブラケット型の内側にいる場合、これd*4+eはb;のthビットをXORします。そうでなければ、何もしません。
すべてのループの最後にb、目的の戻り値の2倍に等しい1ビットの数が含まれます。ただし、これが何ビットかを把握する必要があります。それがサブ機能のf出番です:
f=y=>y&&y%2+f(y>>1)
Ifは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で割ると、答えがあります。