Find the First Bracket Match
Brain-Flak, 685, 155, 151, 137 bytes
(())({<{}({}()<(()()()())>)({}(<>))<>{(({})){({}[()])<>}{}}{}<>
([{}()]{})(({})){{}({}[()])(<()>)}{}(<>)<>{{}<>{}({}<>)}{}(<>[]<>)>()}<>)
Try it online!
136 bytes of code, plus one byte for -a
. One indexed.
530 bytes golfed off! That's probably the largest golf I've ever done.
14 bytes saved thanks to Riley!
This abuses a formula of the opening/closing parenthesis: if you take the ASCII values, increment it by one, and take modulo of 4, the openers (({[<
) will always get 0
or 1
, whereas the closers ()}]>
) will always get 2 or 3.
Explanation:
#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
<>)
05AB1E, 17 16 10 bytes
-1 thanks to carusocomputing
-6 thanks to Adnan for his amazing insight that "after incrementing, the second last bit is 0 for an opening bracket and 1 for an closing bracket"
Ç>2&<.pO0k
Try it online!
Ç # 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
Vim, 23 bytes
:se mps+=<:>
%DVr<C-a>C1<esc>@"
Try it online!
I'm really sad about this answer. This solution is beautifully elegant and short, but, by default, vim does not consider <
and >
to be matched, so I need 13 bytes of boilerplate code. Otherwise, this would just be 10 bytes.
I would have posted a V answer, but that would only be one byte shorter, namely changing Vr
to Ò
, since Vr
is a common vim-idiom.
This is 1-indexed but could be trivially modified to be 0-indexed by changing the 1
to 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