자바 스크립트 (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
. 그렇다면 d
th 브래킷 유형을 입력하거나 종료 하므로 d
th 비트를 a
로 뒤집습니다 a^=1<<d
. 그렇지 않은,하지만 우리는 경우 입니다 내부 d
일 브라켓 형, 우리는 플립 필요 e
에 번째 비트 d
의 제 4 비트 섹션 b
. 이것은 다음과 같이 수행됩니다.
b^=(a>>d&1)<<d*4+e
(a>>d&1)
d
에서 비트를 반환합니다 a
. 우리가 d
th 브라켓 타입 안에 있다면 , 이것은 1을 반환합니다; 그렇지 않으면 0을 반환합니다. 다음으로 d*4+e
비트 단위로 왼쪽으로 이동 b
하고 결과로 XOR 을 이동합니다. 만약 우리가 d
th 브라켓 타입 안에 있다면 , 이것은 X d*4+e
비트의 b
; 그렇지 않으면 아무것도하지 않습니다.
모든 루핑이 끝나면 b
원하는 반환 값의 두 배에 해당하는 1 비트 수가 포함됩니다. 그러나 우리는 여전히 이것이 몇 비트인지 알아 내야합니다. 그것이 하위 기능 f
이 들어오는 곳입니다.
f=y=>y&&y%2+f(y>>1)
경우 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 결과를 분할하고, 우리의 대답이있다.