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
。そうである場合、d
thブラケットタイプを入力または終了するため、でd
thビットを反転a
しa^=1<<d
ます。それはありませんが、我々は場合はあるの内側d
番目のブラケットの種類、我々は反転する必要があるe
でビット目d
の第4ビットセクションb
。これは次のように行われます。
b^=(a>>d&1)<<d*4+e
(a>>d&1)
のd
thビットを返しますa
。d
thブラケット型の中にいる場合、これは1を返します。それ以外の場合は、0を返します。次に、d*4+e
ビットを左にシフトb
し、結果をXOR します。d
thブラケット型の内側にいる場合、これd*4+e
はb
;のthビットをXORします。そうでなければ、何もしません。
すべてのループの最後にb
、目的の戻り値の2倍に等しい1ビットの数が含まれます。ただし、これが何ビットかを把握する必要があります。それがサブ機能のf
出番です:
f=y=>y&&y%2+f(y>>1)
Ifはy
0で、これは単にそうでなければ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で割ると、答えがあります。