자바 스크립트 (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 바이트를 넘었고 골프를 치기 위해 노력하고 싶지 않았습니다. 어제 노트북에서이 아이디어를 살펴 보았고 골프를 치기 전까지는 그 생각을 멈추지 않기로 결정했습니다. 나는 완전히 새로운 알고리즘 두 개를 작성했는데, 그 중 첫 번째 알고리즘은 수많은 비트 해킹으로 약 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)d에서 비트를 반환합니다 a. 우리가 dth 브라켓 타입 안에 있다면 , 이것은 1을 반환합니다; 그렇지 않으면 0을 반환합니다. 다음으로 d*4+e비트 단위로 왼쪽으로 이동 b하고 결과로 XOR 을 이동합니다. 만약 우리가 dth 브라켓 타입 안에 있다면 , 이것은 X d*4+e비트의 b; 그렇지 않으면 아무것도하지 않습니다.
모든 루핑이 끝나면 b원하는 반환 값의 두 배에 해당하는 1 비트 수가 포함됩니다. 그러나 우리는 여전히 이것이 몇 비트인지 알아 내야합니다. 그것이 하위 기능 f이 들어오는 곳입니다.
f=y=>y&&y%2+f(y>>1)
경우 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 결과를 분할하고, 우리의 대답이있다.