첫 번째 브라켓 경기 찾기


22

이것은 Brain-Flak의 생일로 이어지는 일련의 도전 중 하나였습니다. 자세한 내용은 여기 를 참조 하십시오 .

도전

이 과제의 목표는 완전히 일치하는 대괄호 문자열에서 첫 번째 대괄호 쌍을 찾는 것 ()[]{}<>입니다. 완전히 일치하는 문자열에 대한 DJMcMayhem의 정의 를 빌리려면 :

  • 이 과제의 목적 상 "브래킷"은 다음 문자 중 하나 ()[]{}<>입니다.

  • 여는 괄호와 닫는 괄호가 올바른 순서이고 괄호 안에 문자가없는 경우 괄호 쌍은 "일치하는"것으로 간주됩니다.

    ()
    []{}
    

    또는 내부의 모든 하위 요소도 일치하는 경우

    [()()()()]
    {<[]>}
    (()())
    

    하위 요소는 여러 층으로 중첩 될 수도 있습니다.

    [(){<><>[()]}<>()]
    <[{((()))}]>
    
  • 각 쌍의 브래킷이 올바른 순서로 올바른 개폐 브래킷을 갖는 경우에만 문자열이 "완전히 일치"한 것으로 간주됩니다.

입력

입력은 공백이 아닌 단일 문자열 또는 문자 만 포함하는 문자 배열로 구성되며 ()[]{}<>완전히 일치합니다. i / o 기본값에 해당하는 합리적인 방식으로 입력 할 수 있습니다 .

산출

프로그램 또는 함수의 출력은 첫 번째를 닫는 대괄호의 색인이됩니다. 출력 합니다 일 수 0또는 1인덱스. 다시, 출력은 우리의 i / o 기본값 과 일치하는 합리적인 방식 일 수 있습니다 .

테스트 사례

Input       0-indexed   1-indexed
()          1           2
(<>)        3           4
<[]{<>}>    7           8
{}{}{}{}    1           2
[[]<>[]]    7           8

이것은 이며 가장 적은 바이트 수입니다!


3
Brain-Flak
ofc

1
@EriktheOutgolfer 완료
DJMcMayhem

1
이 기술은 비효율적 인 BF 구현을 작성하는 데 매우 유용합니다.
Esolanging 과일

답변:


2

V , 4 바이트

%Dø.

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

이것은 대부분의 V 답변과 달리 0 인덱싱을 사용합니다. 나는이 대답과 언어가 얼마나 멀리 왔는지를 매우 자랑스럽게 생각합니다. 설명:

%       " Jump to the first bracket match
 D      " Delete everything under and after the cursor
  ø     " Count the number of times the following regex is matched:
   .    "   Any character

<>와 일치시키는 데 필요한 상용구가 없습니까?
Pavel

@Pavel vim에서 그렇습니다. 그러나 V.에서
DJMcMayhem

27

Brain-Flak , 685, 155, 151 , 137 바이트

(())({<{}({}()<(()()()())>)({}(<>))<>{(({})){({}[()])<>}{}}{}<>
([{}()]{})(({})){{}({}[()])(<()>)}{}(<>)<>{{}<>{}({}<>)}{}(<>[]<>)>()}<>)

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

136 바이트의 코드와에 대한 1 바이트 -a. 하나는 색인되었습니다.

530 바이트 골프! 아마도 내가 해본 것 중 가장 큰 골프 일 것입니다.

Riley 덕분에 14 바이트가 절약되었습니다!

이것은 열기 / 닫기 괄호의 공식을 남용합니다. ASCII 값을 가져 와서 1 씩 증가시키고 모듈로 4를 취하면 오프너 ( ({[<)는 항상 0또는 1이고 클로저 ( )}]>)는 항상 2 또는 3을 얻습니다.

설명:

#Push 1
(())

#While true
({<

    #Pop stack height
    {}

    #Compute (TOS + 1) % 4
    ({}()<(()()()())>)({}(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]{})

    #Decrement if positive
    (({})){{}({}[()])(<()>)}{}

    #Push 0 onto alternate
    (<>)

    #Toggle back
    <>

    #Pop two zeros from alternate if closer
    {{}<>{}({}<>)}{}

    #Push height of alternate stack
    (<>[]<>)

#Make each time through evaluate to 1
>()

#Endwhile
}

#Push the number of loops onto the offstack
<>)

8
하나님의 사랑을 위해이 땅에 무엇이 있는가.
Leaky Nun

기본적으로 모든 사람들은 현재 n-1&2/ n+1&2/ -n&2또는 n%7&2여는 괄호와 닫는 괄호를 구별하고 있습니다 ...
ETHproductions

@ETHproductions brain-flak가 효율적으로 계산할 수 있는지 잘 모르겠지만 &2조사해 보겠습니다.
DJMcMayhem

아, 네 생각 인데요 0/ 12/ 3... 을 구별하기 위해 비슷한 일을해야합니다. 이제 살펴 보았지만 긍정적 인 경우 감소하고 있습니다. 멋진 트릭도 :-)
ETHproductions

1
(TOS+1)%4짧아 질 수 있습니다 온라인으로보십시오!
MegaTom

11

05AB1E , 17 16 10 바이트

carusocomputing 덕분에 -1

Adnan 덕분에 "증분 후 두 번째 마지막 비트는 여는 괄호는 0이고 닫는 괄호는 1"이라는 놀라운 통찰력에 감사합니다.

Ç>2&<.pO0k

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

Ç          # Get input as ASCII values
 >         # Increment
  2&       # And with 2 (0 for open and 2 for close brackets)
    <      # decrement 
     .p    # prefixes
       O   # Sum
        0k # Print the index of the first 0

žu여기서 사용할 수있는 것 같습니다.
Magic Octopus Urn

žu8ÝÈÏ아니, 아니 진짜 롤. 기껏해야 여전히 5 바이트입니다. 나는 중괄호 쌍으로 더 많은 분할을 생각하고 단 한 쌍만 남을 때까지 중괄호를 제거하고 제거 된 각 쌍에 대해 카운터를 2 씩 증가시킵니다. 그래도 나는 모르겠다. atm을 사용해보십시오.
Magic Octopus Urn

10 바이트의 경우 : Ç>2&<.pO0k.
Adnan

1
그냥 장난 ASCII 값으로. 증분 후 두 번째 마지막 비트는 0여는 괄호와 1닫는 괄호입니다.
Adnan

11

Vim, 23 바이트

:se mps+=<:>
%DVr<C-a>C1<esc>@"

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

이 답변이 정말 슬프다. 이 솔루션은 기본적으로 정력 고려하지 않습니다 아름답게 우아하고 짧지 만 <하고 >내가 상용구 코드의 13 바이트가 필요하므로 일치시킬 수 있습니다. 그렇지 않으면 이것은 단지 10 바이트입니다.

즉 변화, 나는 V 답변을 게시 한 것입니다, 그러나 그것은 단지 하나의 바이트 짧은 것 VrÒ있기 때문에, Vr일반적인 VIM-관용구이다.

이것은 1 인덱싱되어 사소 변경하여 0 인덱스로 변형 될 수있다 1(A)에 0.

:se mps+=<:>        " Stupid boilerplate that tells vim to consider `<` and `>` matched
%                   " Jump to the bracket that matches the bracket under the cursor
 D                  " Delete everything from here to the end of the line
  V                 " Visually select this whole line
   r<C-a>           " Replace each character in this selection with `<C-a>`
                    " This conveniently places the cursor on the first char also
         C          " Delete this whole line into register '"', and enter insert mode
          1<esc>    " Enter a '1' and escape to normal mode
                @"  " Run the text in register '"' as if typed. Since the `<C-a>` command
                    " Will increment the number currently under the cursor

1
V 답변을 게시 후 :)
Outgolfer Erik

10

젤리 , 11 10 9 바이트

O’&2’+\i0

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

설명

여기서 아이디어는 여는 괄호와 여는 괄호를 구별 할 수있는 "마법 공식"을 찾는 것이 었습니다. 나는 원래 사용했다 O%7&2(즉, "ASCII 코드, 모듈로 7, 비트 및 2"를 취함). @ETHproductions가 제안했다 O’&2(모듈로 7을 감소로 대체 ​​함). 둘 다 한 종류의 대괄호에는 0을, 다른 한 종류에 대해서는 2를 반환합니다. 1 ( )을 빼면 이러한 결과가 -1과 1이됩니다.

나머지 코드는 +\입니다. +\누적 합계를 생성합니다. 대괄호 집합이 올바르게 일치하면 동일한 수의 -1과 1이 포함됩니다. 즉 누적 합계는 0이됩니다. 그런 다음 결과 목록에서 첫 번째 0의 인덱스를 반환하면됩니다. 우리는 그것을 할 수 있습니다 i0.


닫는 괄호를 탐지하기 위해 유사한 접근 방식을 취한 방식에 매료되었습니다. 불행히도 나는 열등한 버전을 발견했다.b*2%7>3
2501

재미있는 접근법! 나는 더 긴 대답 (연습을 위해)을 개발했다. 실제로 당신의 게시물의 첫 번째 감소 대신 재미있게 충분히 제외하고는 실제로 이것으로 골프화했습니다. 대신 증가했습니다. :)
HyperNeutrino

9

망막 , 26 24 바이트

M!`^.(?<-1>([[({<])*.)*

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

결과는 1을 기준으로합니다.

설명

본질적으로 단일 (그리고 읽기 쉬운) 정규식을 기반으로하는 매우 다른 Retina 솔루션. 이것은 균형 그룹을 사용하여 균형 문자열을 일치시키기 위해 어제 발견 한 새로운 기술을 사용 합니다 .

M!`^.(?<-1>([[({<])*.)*

정규식과 일치하는 모든 항목을 찾아 ( M) 반환 !합니다 ^.(?<-1>([[({<])*.)*. 이 정규식은 문자열의 첫 문자를 건너 뛰고 균형 그룹을 사용하여 중첩 깊이를 추적합니다. [({<깊이 를 늘리면 (그룹별로 유지되는 트랙 1) 다른 캐릭터가 깊이를 줄입니다 (원칙적으로 .대괄호를 열어 깊이를 줄일 수는 있지만 정규 표현식이 탐욕스럽게 일치하기 때문에 백 트래커는 절대로 시도하지 않습니다. ). 이상한 트릭은 있다는 것입니다 (?<-1>...)은 분리 장치 그룹 1은 A 균형 그룹에서 터지는 때문에 작동시 발생 끝에 그룹의. 이것은 표준 접근 방식보다 2 바이트를 양식으로 저장합니다.((open)|(?<-2>close))*. 첫 번째 항목을 닫는 대괄호에서 일치하는 항목이 반드시 중지됩니다. 건너 뛰기 때문에 스택 깊이에 포함되지 않으며 스택 깊이는 음수가 될 수 없습니다.

이 일치의 길이는 찾고있는 괄호의 0 기반 색인입니다.


이 문자열에서 빈 일치 항목 수를 계산하십시오. 빈 정규 표현식은 문자열에 문자보다 항상 한 번 이상 일치하므로 찾고있는 대괄호의 1 기반 색인을 제공합니다.


훌륭합니다!
Pavel

더 짧은 접근법 : 첫 번째 부분과 일치하는 대신 문자열의 두 번째 부분을 삭제하십시오. 나는 당신이 줄의 길이를 측정하는 방법을 좋아합니다, btw!
Leo

@ 레오 정말 깔끔합니다! 별도의 답변으로 게시 할 수 있습니다 :)
Martin Ender

좋아, 균형 잡힌 현을위한이 새로운 속임수는 훌륭합니다 : D
Leo

6

레티 나 , 24 바이트

.(([[({<])|(?<-2>.))*$


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

이것은 Martin Ender의 솔루션에서 영감을 얻은 입니다.

설명

첫 번째 줄은 문자와 일치하는 정규 표현식으로, 기본 문자열의 끝까지 균형 잡힌 문자열이 이어집니다 (이 정규 표현식에서 균형 그룹이 사용되는 방법에 대한 자세한 설명은 Martin의 답변 참조). 정규 표현식은 왼쪽에서 오른쪽으로 일치하는 항목을 찾기 때문에 가장 긴 균형 잡힌 적절한 접미사, 즉 첫 번째를 닫는 대괄호 다음에 대괄호 자체를 찾습니다.

다음 줄은 비어 있으므로 일치하는 항목을 빈 문자열로 바꿉니다. 즉, (0- 인덱싱 된) 원하는 결과를 얻기 위해 나머지 문자 만 계산하면됩니다.

마지막 빈 줄은 문자열에서 빈 문자열의 일치 횟수를 계산합니다. 이는 문자열의 문자 수보다 1이 많으며 1- 인덱싱 결과와 같습니다.


어제 균형 잡힌 문자열을 일치시키는 새로운 기술을 찾았습니다 .tio.run / ## K0otycxL / K @ q4Z7wX0 / D3kbX0E4jOlqj2iZWU0tPU0uFi @ v / … 과거 ...)
마틴 엔더

5

펄 5 , 28 바이트

Martin Ender의 Retina answer 에서 .대신을 사용하여 6 바이트를 절약했습니다 .[>})\]]

27 바이트의 코드 + -p플래그.

/([<{([](?0)*.)+?/;$_=$+[0]

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

재귀 정규 표현식, 정말 아름다운 발명품.
정규식은 여는 괄호 ( [<{([]), 재귀 호출 ( ?0), 닫는 괄호 ( .) 를 찾습니다 . 이 모든 것은 무의미한 ( +?)이므로 처음부터 가능한 한 짧게 일치합니다. 경기 종료 지수가 정답이며, 이에 따라에서 찾을 수 있습니다 $+[0].


4

자바 스크립트 (ES6), 55 53 52 바이트

@Adnan 덕분에 1 바이트 절약

f=([c,...s],i=1)=>(i-=-c.charCodeAt()&2)&&1+f(s,++i)

모든 여는 괄호마다 char-code mod 4를 사용하면 0 또는 3이됩니다. 닫는 괄호의 경우 1 또는 2를 제공하므로 괄호의 문자 코드를 무시하고 (비트를 빼고 1을 뺀) 두 번째로 중요도가 낮은 비트를 가져 와서 여는 괄호와 닫는 괄호를 구분할 수 있습니다. 즉 n&2.


내가 대신의 생각 n-1&2, -n&2또한 작동?
Adnan

@Adnan Hmm, 당신이 옳다고 생각합니다. 감사!
ETHproductions

4

C, 75 72 56 55 54 45 바이트

a;f(char*s){return(a-=(-*s++&2)-1)?1+f(s):0;}

온라인에서 작동 하는지 확인하십시오 .

출력을 0 인덱스 대신 1 인덱스로하려면 마지막 0을 로 바꿉니다 1.


4

Python 2.7 + Numpy, 85 79 바이트

코드 골프에 대한 나의 첫 번째 시도 :

from numpy import*
lambda s:list(cumsum([(ord(x)+1&2)-1for x in s])).index(0)

1
사이트에 오신 것을 환영합니다!
DJMcMayhem

1
람다의 이름을 지정할 필요는 없습니다. g =를 제거 할 수 있습니다.
Pavel

4

Brain-Flak , 97 바이트 (코드는 96, 플래그는 1)

{}<>(())({<(<()>)<>({<({}[()])><>([{}]())<>}{})<>(<{}>())<>{({}[()])<>([{}])<>}{}<>({}{})>()}{})

-a플래그로 실행하십시오 .

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

설명:

#Skip the first open bracket 
{}

#Place a 1 on stack B, representing the nesting depth
<>(())

#Start a loop, until the depth is 0
({<

 #Divide the ASCII code by 2, rounding up
 (<()>)<>({<({}[()])><>([{}]())<>}{})<>

 #Replace TOS B with a 1
 (<{}>())

 #Swap back to stack A
 <>

 #Negate the 1 on stack B n times (n = ASCII value+1/2)
 {({}[()])<>([{}])<>}{}

 #Swap back to stack B
 <>

 #Add the 1/-1 (depending on Open/close bracket) to the nesting depth accumulator
 ({}{})

 #Count loop cycles
 >()

#end loop, print result implicitly by pushing to the stack 
}{}) 

잘 작동합니다.


3

망막 , 34 바이트

^.
!
T`([{}])`<<<>
+T`p`!`<!*>
\G!

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

결과는 0부터 시작합니다.

설명

^.
!

첫 문자를로 바꿉니다 !. 이로 인해 찾고있는 대괄호가 일치하지 않습니다.

T`([{}])`<<<>

괄호, 대괄호 및 중괄호를 꺾쇠 ​​괄호로 변환하십시오. 문자열이 완전히 일치한다고 보장되므로 실제 유형에 전혀 신경 쓰지 않으므로 다음 단계에서 약간의 바이트가 절약됩니다.

+T`p`!`<!*>

+모든 일치하는 각 문자 <!*>!s로 반복해서 ( ) 바꿉니다 . 즉, 더 이상 처리되지 않은 괄호가 포함되지 않은 괄호 쌍을 일치시키고 더 큰 느낌표로 바꿉니다. 이렇게하면 일치하지 않는 닫는 대괄호를 제외한 전체 문자열이 느낌표로 바뀝니다.

\G!

선행 느낌표의 수를 세십시오. 첫 느낌표의 0부터 시작하는 위치와 같습니다 (예 : 일치하지 않는 대괄호). \G앵커 이것이 포함되지 않는 이유는 이전에 각각 일치 !했다 브라켓 후들.


나는 당신이 홈페이지에서 답을 보았고 그것이 일종의 정규 표현식을 사용할 것이라는 것을 알았습니다.
Christopher

@ Christopher Eh, 이것은 방금 게시 한 다른 Retina 답변과는 달리 정규 표현식을 거의 사용하지 않습니다.
Martin Ender

esh 정규식 많이?
Christopher

왜되지 않은 작업?
Leaky Nun

@LeakyNun (?!(2))그냥 있기 때문 입니다 (?!2). 당신은 아마 의미 (?(2)(?!))(?2)!). 당신은 또한 탈출을 잊어 버렸고 ]마지막 +이되어야합니다 *.
Martin Ender

2

PHP, 116 바이트

for($l=["("=>")","["=>"]","{"=>"}","<"=>">"][$f=$argn[0]];;$d>0?$i++:die("$i"))$d+=$f!=($n=$argn[$i])?$n==$l?-1:0:1;

온라인 버전


PHP로 시작할 필요는 <?php없습니까?
Pavel

@Phoenix : 시작 태그가 필요없는 독립형 PHP 인터프리터가 있습니다. 그것이 골프에 일반적으로 사용되는 것입니다.

@ ais523이 경우 PHP는 -R 옵션을 사용하여 명령 행에서 실행됩니다.
Jörg Hülsermann

2

파이썬 , 76 바이트

f=lambda s,r=[],i=0:(i<1or sum(r))and f(s[1:],r+[(ord(s[0])+1&2)-1],i+1)or i

Adnan (및 다른 것)이 발견 한 많은 사람들이 사용하는 open vs close trick의 플래그로 서수 2 LSB를 사용하는 재귀 함수. -1열기 및 1닫기 의 누적 합 이 0에 도달하면 테일 이 발생합니다. 인덱스는을 사용하는 것보다 바이트 저렴하므로 변수에 보관되며 len(r)인덱싱은 1 기반입니다.

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


2

루비, 35 34 바이트

p$_[/[<{(\[](\g<0>)*[>})\]]/].size

Dada의 Perl5 답변을 기반으로 합니다. 출력은 1 인덱스입니다. -n옵션 (암시 적 while gets루프)으로 Ruby 인터프리터를 호출해야합니다 .

편집 : 이것은 35 34 바이트이지만이 대답을 더 줄이기 위해 가능한 또 다른 출발점입니다.

p$_[/[<{(\[](\g<0>)*[>})\]]/]=~/$/

Edit2 : 이후에 불필요한 공백이 제거되었습니다 p.

Edit3 : 몇 가지 더 많은 34 바이트 답변.

~/[<{(\[](\g<0>)*[>})\]]/;p$&.size
p~/[<{(\[](\g<0>)*[>})\]]/+$&.size

2
PPCG에 오신 것을 환영합니다!
Pavel

1
매우 감사! :)
Ray Hamel


1

배치, 172 바이트

@set/ps=
@set/ai=d=0
:l
@set/ai+=1,d-=1
@set c="%s:~,1%"
@set "s=%s:~1%
@for %%a in ("<" "(" "[" "{")do @if %%a==%c% set/ad+=2&goto l
@if %d% gtr 0 goto l
@echo %i%

1- 색인. <>물론 Batch의 특수 문자이므로 인용문을 인용해야 할뿐만 아니라 goto레이블 을 만드는 등의 트릭도 할 수 없습니다 .


1

R, 126 바이트

s=readline();i=0;r=0;for(c in strsplit(s,"")[[1]]){if(grepl("[\\[\\(\\{<]",c))i=i+1 else i=i-1;if(i==0){print(r);break};r=r+1}

0

C, 127 바이트

온라인 시도

c(x){x-40&x-60&x-91&x-123?-1:1;}
f(i,t)char*t;{return i?f(i+c(*t),t+1):t;}
s(char*t){return f(c(*t),t+1)-t;}

산출

2   ()
4   (<>)
8   <[]{<>}>
2   {}{}{}{}
8   [[]<>[]]

모든 의견, downvoter.
Khaled.K

나는 downvoter가 아니었지만, 훨씬 더 짧은 C 제출이 이미 도움이되지 않았다고 생각합니다.
Ørjan Johansen '
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.