연동 브래킷


30

()[]{}<>4 개의 각 대괄호 유형이 일치하도록 배열 된 각 문자 중 하나를 포함하는 8 바이트 문자열을받는 프로그램 또는 함수를 작성하십시오 . 예를 들어, ]<([){}>대괄호가 일치하지 않기 때문에 입력이 유효하지 않습니다 (다른 모든 것이 일치하더라도).

인쇄 또는 정수를 반환 0하는 6네 개의 브래킷 유형의 가능한 여섯 짝의 대부분이 연동하는 방법 있음을 나타냅니다. 한 유형의 하나의 브래킷이 다른 유형의 브래킷 사이에 정확히 발생하면 브래킷 유형 쌍이 인터 로킹 된 것으로 간주됩니다. 그래서 ([)][(])연동되지만 ()[], [](), ([]), 및 [()]아니다.

바이트 단위의 가장 짧은 코드가 이깁니다.

입력 / 출력 예

()[]{}<> : 0
([{<>}]) : 0
<>{[]}() : 0
{<>([])} : 0
<(>)[{}] : 1
<[({)}]> : 1
[{<}]>() : 2
{<>([}]) : 2
<{(>})[] : 3
[(]<){>} : 3
<([>{)}] : 4
(<{[>})] : 4
(<[{)>}] : 5
<{[(>})] : 5
[{<(]}>) : 6
(<{[)>}] : 6

답변:


17

CJam, 18

l7~f&_f{\/~;&}s,2/

골프 아이디어에 대한 isaacg 감사합니다 :)
온라인으로 시도 하거나 모든 예를보십시오

설명:

l         read a line of input
7~f&      clear the lowest 3 bits of each character
           the goal is to convert brackets of the same type to the same char
_         duplicate the resulting string, let's call it S
f{…}      for each character in S, and S (the char and S are pushed every time)
  \       swap the character with S
  /       split S around that character, resulting in 3 pieces:
           before, between, after
  ~       dump the pieces on the stack
  ;       pop the last piece
  &       intersect the first 2 pieces
          after the loop, we have an array of strings
          containing the chars interlocking to the left with each char of S
s         join all the string into one string
,         get the string length
2/        divide by 2, because S has duplicated characters

1
아, 그래서 당신은 CJam을 만든 사람입니까? CJam의 답변에 의해 잃어버린 모든 답변에 대해 나에게 빚진 것입니다! ;)
kirbyfan64sos

6
@ kirbyfan64sos 잘, 당신이 이기고 싶다면 그것을 배우는 것이 좋습니다 :)
aditsu

9
7~f&? 나는이 대답을 이미 좋아하고 나머지 부분조차 읽지 않았습니다.
Dennis

11

파이썬 2, 163 바이트

def f(b,e='([{<)]}>',q=range(4)):
 b=[b[b.index(e[j])+1:b.index(e[j+4])]for j in q]
 print sum(sum(abs(b[k].count(e[j])-b[k].count(e[j+4]))for j in q)for k in q)/2

일치하는 각 괄호 쌍 사이의 내용을보고 존재하는 개별 왼쪽 또는 오른쪽 괄호 수를 계산합니다. 이들의 합을 2로 나눈 값이 출력됩니다.

나는 그것이 나보다 더 나은 골퍼들에 의해 더 많이 골프를 칠 수 있다고 확신합니다.


31
글쎄요. 캘빈이 답을 올렸습니다. 종말은 우리에게 있습니다.
Alex A.

4

GNU sed -r, 147

이 메타 답변에 따라 출력이 단항으로 표시됩니다 .

y/([{</)]}>/
s/.*/\t& & & & /
:b
y/)]}>/]}>)/
s/\S*>(\S*)>\S* /\1\t/
t
s/\S* //
:
s/(\t\S*)(\S)(\S*)\2(\S*\t)/\1\3\4/
t
s/\S *$/&/
tb
s/\s//g
s/../1/g

참고 : 정확한 점수를 얻으려면 \t실제 tab문자로 바꾸십시오. 그러나 프로그램은 GNU sed와 함께 작동합니다.

온라인으로 사용해보십시오 .


3

펄, 77 바이트

76 코드 + 1 스위치

perl -pe 'y/)]}>/([{</;for$x(/./g){$h{$x="\\$x"}++&&s!$x(.*)$x!$z+=length$1,$1!e}$_=$z'

STDIN에서 입력을 가져오고 모든 입력에 대해 프로그램을 새로 시작해야합니다.

설명

  1. 모든 닫는 괄호를 열린 괄호 ( y/.../.../)로 교체하십시오 .
  2. 그런 다음 입력 문자열 ( for$x...) 의 모든 문자에 대해 문자 ( $h{$x}++) 의 카운터를 늘리십시오 .
  3. 캐릭터가 두 번째 인 경우 두 어커런스 ( length $1) 사이의 거리 를 확인하고이 캐릭터의 두 어커런스를 문자열에서 제거하십시오. 예를 들어 문자열이 ([{([{<<인 경우 두 개의 문자 [와 두 개의 문자 {사이에 문자가 있습니다 (. 애프터 (S가 처리 된 문자열이된다 [{[{<<우리는 전체 개수 (2 추가 $z연동 브래킷).
  4. 결과는 $z( $_=$z) 에서 가져옵니다.

3

Pyth, 20 바이트

JmC/CdTzlsm@FPcsJd{J

테스트 스위트

JmC/CdTz: 먼저 각 입력 문자를 문자 코드 ( Cd)를 10으로 나눈 문자 코드 ( )로 매핑하여 각 기호 쌍을 단일 문자로 변환합니다 / T. 이는 각 쌍마다 동일하지만 모든 쌍마다 다릅니다. 결과 번호는 나중에 공개 할 목적으로 문자로 다시 변환됩니다 ( C). 결과 문자 목록이에 저장됩니다 J.

lsm@FPcsJd{J: 이제 J( {J) 의 고유 문자를 매핑합니다 . J현재 문자를 델리 미터 ( csJd) 로 연결 하여 형성된 문자열을 자르는 것으로 시작합니다 . 두 번째 그룹과 첫 번째 또는 세 번째 그룹에 나타나는 경우 한 쌍의 괄호가 현재 쌍과 겹칩니다. 이중 계산을 피하기 위해 첫 번째와 두 번째 그룹 사례 만 계산합니다. 따라서 세 번째 그룹 ( P)을 제거 하고 나머지 그룹 ( @F)을 교차시킵니다 . 마지막으로 오버랩 문자 ( s)를 연결하고 결과 길이 ( )를 인쇄합니다 l.


3

파이썬 3, 107

t=0
s=""
for x in input():s+=chr(ord(x)&~7)
for x in s:a=s.split(x);t+=len(set(a[0])&set(a[1]))
print(t//2)

CJam 솔루션을 기반으로합니다.


3

망막 , 128 (108) 64 62 55 바이트

(T`)]>}`([<{
(\D)(.*)\1(.*)
\n$2\n$3
(?=(\D).*\n.*\1)
1
\n
<empty>

어디 <empty>빈 후행 라인을 나타냅니다. 계산을 위해 각 줄을 별도의 파일에 넣고 \n실제 줄 바꿈 문자로 바꿉니다. 편의상 -s단일 파일 의 플래그 와 동일한 코드를 사용할 수 있습니다 .

(T`)]>}`([<{
(\D)(.*)\1(.*)
#$2#$3
(?=(\D)[^#]*#[^#]*\1)
1
#
<empty>

출력은 단항 입니다.

설명

첫 번째 (는 반복이 문자열 변경을 중지 할 때까지 Retina에게 전체 코드를 루프로 실행하도록 지시합니다. 이 경우 각 브래킷 유형마다 한 번씩 항상 네 번 반복됩니다.

T`)]>}`([<{

이렇게하면 각 닫는 괄호가 해당 여는 괄호로 바뀌므로 나중에 간단한 역 참조로 해당 괄호를 일치시킬 수 있습니다. (이 단계는 첫 번째 반복 후에 no-op가됩니다. T이미 백틱이 필요 했기 때문에 루프에만 포함 되므로 (2 바이트 대신 1 개만 추가하면 됩니다.)

(\D)(.*)\1(.*)
\n$2\n$3

이렇게하면 가장 왼쪽 대괄호 쌍이 줄 바꾸기로 바뀝니다. 우리는 계산을 위해 루프에서 나중에 추가 \D하는 것과 브래킷을 구별 하는 데 사용 합니다 1. (.*)단 한 쌍의 교체 단부 보장하지만 AT는 (있다는 이유 일치하지 중첩 가능).

(?=(\D).*\n.*\1)
1

전체 정규 표현식이 미리 보이므로 position 과 일치합니다 . 보다 구체적으로는 방금 개행으로 바꾼 다른 괄호로 분리 된 각 괄호 쌍의 한 위치와 일치합니다. 1이 위치 각각에 A 가 삽입됩니다. 우리는 1다른 정규 표현식에 영향을 미치지 않기 때문에 s를 그대로 둘 수 있습니다 ( \Ds는 실수로 일치하지 않기 때문에 ).

\n
<empty>

마지막으로 줄 바꿈 (즉, 현재 유형의 브래킷에 대한 자리 표시 자)을 제거합니다. 즉, 나머지 문제를 3 유형의 브래킷 만 포함하는 길이가 6 인 문자열로 줄 였지만 그렇지 않으면 정확히 동일하게 작동합니다.

마지막으로, 1우리가 삽입 한 s 만 남게되고 그 양은 인터 로킹 브래킷의 수와 정확히 일치합니다.


2

자바 스크립트 (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 바이트를 깎아서 몇 바이트 더 짧아졌습니다.

작동 원리

먼저 변수 ab로 설정합니다 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 결과를 분할하고, 우리의 대답이있다.


1

Oracle SQL 11.2, 206 바이트

WITH v AS(SELECT b,MIN(p)i,MAX(p)a FROM(SELECT SUBSTR(TRANSLATE(:1,'])>}','[(<{'),LEVEL,1)b,LEVEL p FROM DUAL CONNECT BY LEVEL<9)GROUP BY b)SELECT COUNT(*)FROM v x,v y WHERE x.i<y.i AND x.a<y.a AND y.i<x.a;

언 골프 :

WITH v AS( -- Compute min and max pos for each bracket type
           SELECT b,MIN(p)i,MAX(p)a 
           FROM   ( -- replace ending brackets by opening brakets and split the string  
                    SELECT SUBSTR(TRANSLATE(:1,'])>}','[(<{'),LEVEL,1)b,LEVEL p 
                    FROM DUAL 
                    CONNECT BY LEVEL<9
                  )
           GROUP BY b
         )
SELECT COUNT(*)
FROM   v x,v y
WHERE  x.i<y.i AND x.a<y.a AND y.i<x.a -- Apply restrictions for interlocking brackets  
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.