[Question]
  [
The challenge is simple, find the matching parentheses for every one of the parentheses in a given string input
E.g.
```
()()() -> [1, 0, 3, 2, 5, 4]
```
Always start with the ending parentheses index before the starting parentheses, which is why `()` becomes `[1,0]`, not `[0,1]`, unless the parentheses is stacked e.g. `(())`, where the position of the parentheses must match the index so `(())` is `[3, 2, 1, 0]`
## Test Cases:
```
() -> [1, 0]
()(()) -> [1, 0, 5, 4, 3, 2]
()()() -> [1, 0, 3, 2, 5, 4]
((())) -> [5, 4, 3, 2, 1, 0]
(()(())) -> [7, 2, 1, 6, 5, 4, 3, 0]
```
You may output the indexes in the form of a list, or in the form of a string representation if so, but the output indexes must be distinguishable from each other e.g. `1 0`
You are allowed to use 0-index or 1-indexed lists/arrays.
**This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") so shortest bytes wins!**
  
[Answer]
# x86-64 machine code, 21 bytes
```
5A 58 89 0A 8D 51 57 AB FF C1 45 31 C9 AC 84 C0 7B EE 75 F1 C3
```
[Try it online!](https://tio.run/##XVLPb9sgFD6bv@KNqSokTpR03TTFyy7ddZedJrk@OIBjJgIW4M5Z5H993qNJ27UHw3sf7/sBsui6xV6IaarDARj8oIws98btagMN8d0m61wHXg7kXNRYHNwDlAhVOSiB/XJ3jApWw@dvxCRCH1rw6eBcSU2yEF2QJNNWvKbcfiTNJhucT/BFzjgZdiSLKkSoTY4fyX51DnyHu/0DBnevIuEUeEHUEJW3QO8onB6cltAwbSPMvAq9iTkIZ1FHtLWHWeDFSMh7TGF6qeBLiFK7ZfuVkP@nkrGogwplBVs4UcZpjgtj/FLwM5IATseCJL9DrS3j5ESyBi/DXunBBp41OclwJkuUc8JyvaoKRBr2lDjy1HceZxpGrwJ9gh6VE1NjrlUBsdRVAXo@R9EXAlxpZFzEdXUW62PKwq7v7XUCRvI8fm@/16LVVuFLSbWh6Th5DMkjhyO20sHpRX118xP1j1vGehv03ir5eM8ZbxbrNS@H@Rw9R/jdaqOAHeEd6gx3H5LumxjjNP0Vjan3YVocPt3igv/gFn2U@Qc "C++ (gcc) ‚Äì Try It Online")
Following the standard calling convention for Unix-like systems (from the System V AMD64 ABI), this takes in RDI an address at which to place the result, as an array of 32-bit integers; and the address of the input, as a null-terminated byte string, in RSI.
In assembly:
```
.global f
rp: pop rdx           # (Right parenthesis) Pop the matching left parenthesis's
                      #   corresponding output address into RDX.
    pop rax           # Pop its index into RAX.
    mov [rdx], ecx    # Put the current index at the popped address.
    .byte 0x8D        # Subsumes the next two instructions into 'lea edx, [rcx+0x57]'.
lp: push rcx        # (Left parenthesis) Push the index onto the stack.
    push rdi        # Push the corresponding output address onto the stack.
    stosd             # Store EAX at [RDI] and advance the pointer.
    inc ecx           # Increment the index.
    .byte 0x45        # REX.RB prefix byte; changes the next instruction to 'xor r9, r9'.
f:  xor ecx, ecx    # (Start here.) Set ECX to 0 (index in string).
    lodsb             # Load a character of the string into AL, advancing the pointer.
    test al, al       # Set the flags based on that character.
    jpo rp            # Jump if it has an odd number if 1 bits (for a right parenthesis).
    jnz lp            # Jump if it is nonzero (for a left parenthesis).
    ret               # Return (for the null terminator).
```
[Answer]
# [BQN](https://mlochbaum.github.io/BQN/), 37 bytes[SBCS](https://github.com/mlochbaum/BQN/blob/master/commentary/sbcs.bqn)
```
{‚åΩÀò‚åæ(‚àò‚Äø2‚ä∏‚•ä)¬®‚åæ(((1‚ä∏‚â†++`)¬Ø1‚ãÜùï©-@)‚ä∏‚äî)‚äíÀúùï©}
```
[Run online!](https://mlochbaum.github.io/BQN/try.html#code=RiDihpB74oy9y5jijL4o4oiY4oC/MuKKuOKliinCqOKMvigoKDHiirjiiaArK2Apwq8x4ouG8J2VqS1AKeKKuOKKlCniipLLnPCdlal9CgpGICIoKSgoKSki)
`(1‚ä∏‚â†++`)¬Ø1‚ãÜùï©-@` generates a depth map for the brackets. Coupled with Under, we can group the indices by depths, and reverse the grouping to get back the original array shape.
`‚åΩÀò‚åæ(‚àò‚Äø2‚ä∏‚•ä)¬®` reverses each pair of bracket indices, putting them in the correct place.
-1 and -4 with ovs' help.
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), 51 bytes
```
a=>a.map((c,i)=>a[a[i]=a.lastIndexOf(c>'('&&-1)]=i)
```
[Try it online!](https://tio.run/##JYyxDoIwFEV3vqITfS@Bl7iZkLIx6CCDI2F4KRRrsCW0MRrjtyPIcu49d7h3fnLQs51i7nzXL0YtrEqmB08AOrO4SsONbRXTyCGeXNe/agO6lCDTND9gqywuErAA3AC4t3342yZbrERJYRptBFlIJOPnivUNolCl@CRCaO@CH3sa/QCRJu4q18ERMwEGWCjREFFsVz9f6wuFOFs3WPMGXp@L5IvF8gM "JavaScript (Node.js) ‚Äì Try It Online")
Input an array of characters. Output by modify the array in-place.
[Answer]
# [Haskell](https://www.haskell.org/), 112 bytes
```
g(a:x)|a>'('=1|w<-g x=1+w+g(drop w x)
a#b=succ<$>a!map(-1+)b
('(':x)!s=g x:x#(0:s)
(_:x)!(a:s)=a:x#s
_!w=w
(![])
```
[Try it online!](https://tio.run/##FczLCoMwEIXhfZ5iYgRnEKFuxfFFSpHRlij1hmlJFr57msJZHfj@Sdz7tSwxWpQm0CVdgQXXl28rC4Hr0pcWn@d@gIdASszA7juObd6JXuXAqi5pUJhQ0tpxQk0weGscKez/X@o64hQ3TvXas1cTo74/KK4yb8BwnPP2gRwmyBAJKS2LPw "Haskell ‚Äì Try It Online")
With some comments:
```
-- Get the 1-based index of the first unmatched ')'
g :: [Char] -> Int
g(a:x)|a>'('=1|w<-g x=1+w+g(drop w x)
-- Common part of the two cases in (!); updates the indices
(#) :: [Char] -> [Int] -> [Int]
a#b=succ<$>a!map(-1+)b
-- Main function, iterates through the string
(!) :: [Char] -> [Int] -> [Int]
-- '(' are replaced by the result of g on the remaining string
('(':x)!s=g x:x#(0:s)
-- ')' are replaced by the index of the matching '(' (stored in the right argument)
(_:x)!(a:s)=a:x#s
_!w=w
h :: [Char] -> [Int]
h=(![])
```
[Answer]
# [Haskell](https://www.haskell.org/), 94 bytes
```
snd.([]%).zip[0..]
z%((i,c):x)|c<')',(j:k,a)<-(i:z)%x=(k,j:a)|v:w<-z=([i],[v])<>w%x
z%e=mempty
```
[Try it online!](https://tio.run/##bc2xboMwFIXhnae4ioJyr2RbnS07SyulS6XulMECUxzAWOAGivLsdenadv3065zWzJ3t@@SGME4Rnkw04mX0o6sBUZ2JgHPwdoHL8yO0ZobYuhmch9fJ9h@1FVmj39Lsa4FFmZPYXCgehCizLUd0rCK50r1SJzoxvMqOGVIcndwoXzV27CoN3W9yUXzTWLiSFbeS1HnJ133A6sEOIX6mweyHGuoxAwiT8xGO0MAB6fAbEOkfpL/lT7hj@qqa3rzPiVchfAM "Haskell ‚Äì Try It Online")
[Answer]
# Python3, 75 bytes
```
def f(a,*s,i=-1):
 for c in a:
  i+=1;s+=i,
  if"("<c:*s,a[i],_=s;a[a[i]]=i
```
[Try it online!](https://tio.run/##NY4xDoMwDEX3nsLKZJcwoG5QnwShKqJEtVQFRLJw@tQWdLHf//K3vR3ls6ZHre8lQsTg79kLtx31N4jrDjNIgqACpOFuyA2LNxEduufc63QYZfIvzkMYDSeWasGy5GJZh@S8VUT6E12eWRfRyXYoAMNXckFbQWroW9a2XVJRrD8)
-2 thx to @KevinCruijessen
-6 thx to @ovs
-10 thx to @loopywalt
-6 thx to @ovs
-4 thx to @loopywalt
## Other solutions:
## Python3, 76 bytes
```
def f(a,s=[]):
 for*s[:0],c in enumerate(a):
  if"("<c:i,v,*_=a[v],a[i],*s=s
```
[Try it online!](https://tio.run/##NY5BCgMhDEX3PUVwFSWLQjdF6klEikyVCq0zGGegp7cG2k3yeeGFv336c62X69bGeKQMGSOx80HbE@S1Gfb2HGiBUiHV/Z1a7AmjXKFkheq22EIHmbuL/ggUfQlk2PGYMvTEXUyFWpFMRP1P@scEaSX/Ijh4Fe4omp5gdpG1tVL7jOML)
[Answer]
# [Python](https://www.python.org), 93 bytes
```
def f(x):
 d=c=0
 for y in x:c-=y<')';x[d]=c;x[k:=x.index(c)]=d;x[d]=[c,k][k<d];c+=y>'(';d+=1
```
[Attempt This Online!](https://ato.pxeger.com/run?1=TY5BbsMgEEX3PsXsGBpsJW0jVXbIRSwWERgVGWPL0Mo-SzfetHfKbQqmUsoGzX_z_5-vn2kN76Pbtu-PoMu3u1CdBo0LrQtQXPJjAXqcYQXjYKllydcLoaRZWiW4jF9f86UyTnULSiq4yqSVrBdtf1GikQe-XgmSRh346a9kNsM0zgH86ouUblN6HCoflHHV3N2UNa7zmK6Iz7ARONjKT9YEJFBegdCdJL37vFkc8zzNxgWM-0zjUPP2yQgaCwaam7e7RJrs7YnBURRIEelDYHBm8MrghcHzDin-h0nOKxEmY4YPD4M9Nnf9Ag)
Takes a list of characters and modifies it in-place.
#### How?
Simply walks the list from left to right. Tracks the bracketing depth (uses negative numbers, so we can unambiguously overwrite them with indices later). Whenever we encounter a level for the second time swap indices with first occurrence.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), ~~19~~ 17 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
'(QvyiN√´N‚ÄöÀÜ]¬Øvy√Ç«ù
```
Input as a list of characters.
[Try it online](https://tio.run/##yy9OTMpM/f@/rFJdIzDT7/Bqv0cNs063xR5aX1Z5uOn43P//o5U0lHTAWBNKw9gQHAsA) or [verify all test cases](https://tio.run/##yy9OTMpM/V9Waa@k8KhtkoKSfaWLEpCrrhGY6Xd4td@jhlmn22IPrS@rPNx0fO5/Jb0wnUNb/kdHK2ko6ShpKsXqKMCYOmAaxsYihaDhUqg6MKQ0sSuJBQA).
**Explanation:**
```
v          # Loop over the characters `y` of the (implicit) input-list:
 y'(Qi    '#  If the current character is a ")":
      N    #   Push the current loop-index
     √´     #  Else:
      N‚Äö   #   Pair the top value on the stack with the current loop-index
        ÀÜ  #   Pop and add this index-pair to the global array
]          # Close both the if-statement and loop
 ¬Ø         # Push the global array of index-pairs
  v        # Loop over each pair of indices:
   y√Ç      #  Bifurcate the current pair; short for Duplicate & Reverse copy
     «ù     #  Insert the values at the indices in the list
           #  (which will use the implicit input-list the first iteration,
           #  and modifies it further every iteration)
           # (after which the list is output implicitly as result)
```
[Answer]
# [Pari/GP](http://pari.math.u-bordeaux.fr/), 61 bytes
-1 byte thanks to [@DialFrost](https://codegolf.stackexchange.com/users/109916/dialfrost).
```
s->for(i=j=1,#a=s,if(")">s[i],s[j]=i;j++,a[a[i]=s[j--]]=i));a
```
[Try it online!](https://tio.run/##JchBCgIxDIXhq4S4SZh04XpIj@GmdBHESotombjx9J0WeZvv/d2OGp59FNDhIZbPQVWbXuVi6lILIWP0VLN4alnr3rZNLNksOksIeUbm3Yb1/vqRQ4jQj/r@TuI6CIVujzs5MwskJF5DgSXivxYYM48T "Pari/GP ‚Äì Try It Online")
[Answer]
# [Perl 5](https://www.perl.org/), 82 bytes
```
sub f{($_,$i)=(@_,0);/\((?R)*\)/?(reverse($i..$i-1+($l=length$&)),f($',$i+$l)):()}
```
[Try it online!](https://tio.run/##XY9NT8JAEIbv/Io3zeLOyPCpeIBUejeRhHgD0kTd1o211FKMhvDb67bUIOxp33mendnJTJ6My3K7e0a0JxWKsuxTEMqAp/0V0WzB1yvuzyg3XybfGlK211O2O@yQSvzEpHHxpq6YJSKl3eOOSpgnxIcy2uTUWgKaWKM6/j2WQ8FgDaylIUTs6B8RjAW3ghvB6MxiOrMqfnT/WVWrxjp1EVxMrOcd/3LJed8CPn7chqIM@4EKp3UhiH23nOUqZblNi8hrd@@2gPnOzEthXidod4cjV0C8KU7BptnORWVXqSfwAmU8mE93iT3MoDfvGhPox/kT5g@6EaTG09ah/AU "Perl 5 ‚Äì Try It Online")
[Answer]
# x86-16 machine code, 21 bytes
```
00000000: 33db ac3c 2974 0353 eb07 5888 0193 8801  3..<)t.S..X.....
00000010: 9343 e2ee c3                             .C...
```
Listing:
```
33 DB       XOR  BX, BX             ; start index counter at 0 
        P_LOOP: 
AC          LODSB                   ; AL = next char in input string 
3C 29       CMP  AL, ')'            ; is it an end paren? 
74 03       JZ   END_PAREN          ; if so, jump to handle
53          PUSH BX                 ; else, push index of left paren to stack 
EB 07       JMP  NEXT_PAREN         ; continue loop 
        END_PAREN: 
58          POP  AX                 ; AL = index of last start paren 
88 01       MOV  [DI+BX], AL        ; write to output at current index of input string 
93          XCHG AX, BX             ; AL = current index of input string 
88 01       MOV  [DI+BX], AL        ; write to output at index of last start paren 
93          XCHG AX, BX             ; restore index counter to BX 
        NEXT_PAREN: 
43          INC  BX                 ; increment counter 
E2 EE       LOOP P_LOOP             ; continue string loop 
C3          RET
```
Custom calling convention - input string at `[SI]`, length in `CX`, output to buffer at `[DI]`.
Tests with DOS DEBUG:
[![enter image description here](https://i.stack.imgur.com/YqTVh.png)](https://i.stack.imgur.com/YqTVh.png)
[![enter image description here](https://i.stack.imgur.com/ecLn2.png)](https://i.stack.imgur.com/ecLn2.png)
[![enter image description here](https://i.stack.imgur.com/zNn6M.png)](https://i.stack.imgur.com/zNn6M.png)
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), 67 bytes
```
\((?=((\()|(?<-2>.))*(?<=(.+)))|(?<=(.*).((\))|(?<-6>.))*).
$.3$.4 
```
[Try it online!](https://tio.run/##JYohDoAwEAR9X4Go2C3pCSAo2n6kBoHAIAiSvx/toWZnM/fxnNeuWoGSgAq@KFucspChrQQZSTvbDJTW/BpXayjOy@xlGVRBBwI0sFuXDnv5AQ "Retina 0.8.2 ‚Äì Try It Online") Link includes test cases. Assumes input is a balanced string of `()`s. Explanation: The first alternation matches a `(`, skips over any balanced `()`s, then captures the resulting index, while the second alternation matches in reverse, skipping back over any balanced `()`s and an implied `(` before capturing the resulting index, then matching an implied `)`. Fortunately `$.` outputs an empty string if the group was not captured at all, so we can just output the length of whichever capture was successful followed by a separator.
[Answer]
# [SNOBOL4 (CSNOBOL4)](http://www.snobol4.org/csnobol4/), ~~144~~ 136 bytes
```
	I =INPUT
	M =BAL | ''
N	I POS(X) LEN(1) . B @X	:F(END)
	B ")"	:F(L)
	I @O '(' M B POS(X) 	:(O)
L	I POS(X) M @O ')'
O	OUTPUT =O	:(N)
END
```
[Try it online!](https://tio.run/##RY0xC8IwFITnvF9xdMl7iyA4FQI1WCGQ5BVsobOz2KGr/z0@RRBuueO7u/253bfHqTWXEFKdlplcQYjnjBe8p2r5pDdeBXmsfBQcEDGsrr/yWC9CLqKT7mOzmYRB4dmjGPXruZ5VKP@HyhcST@p0me0SQQ2qQrbYGrOYRN4 "SNOBOL4 (CSNOBOL4) ‚Äì Try It Online")
```
	I =INPUT			;* Read input
	M =BAL | ''			;* Alias: M is BAL (the shortest, non-null balanced string) or the empty string
N	I POS(X) LEN(1) . B @X	:F(END)	;* extract the next character of I as B, and store the position after B as X
	B ")"	:F(L)			;* If B matches ")", goto next line, else goto L
	I				;* In I, match:
	  @O				;* the position before the match as O
	     '(' M B			;* "(", a balanced string (or nothing), and ")"
		     POS(X) 	:(O)	;* ending at position X, then goto O
L	I POS(X) M @O ')'		;* In I, match, starting at position X, a balanced string, storing position as O, followed by ")"
O	OUTPUT =O	:(N)		;* Output O and goto N
END
```
[Answer]
# APL+WIN, 42 bytes
Prompts for input string. Index origin = 1
```
(,‚åΩ((.5√ó‚ç¥n),2)‚ç¥n)[‚çãn‚Üê‚çã+\(~n)-¬Ø1‚Üì0,n‚Üê')'=‚éï]
```
[Try it online! Thanks to Dyalog Classic](https://tio.run/##SyzI0U2pTMzJT9dNzkksLs5M/v@ob6qvz6O2CcZcQJanP5BlyPWooz3tv4bOo569Ghp6poenP@rdkqepY6QJpqMf9XbnAZUBKe0Yjbo8Td1D6w0ftU020AGJqmuq2wINiv0PNIPrfxqXuoamOheY0tDQhDM1YaIgQU11AA "APL (Dyalog Classic) ‚Äì Try It Online")
[Answer]
# [Curry (PAKCS)](https://www.informatik.uni-kiel.de/%7Epakcs/), 55 bytes
```
g .zip[0..]
g[]=[]
g((i,'('):x++(j,')'):y)=j:g x++i:g y
```
[Try it online!](https://tio.run/##NYxNC4MwDIbv/RVZGZjgBzsX6n2HscOOIkNkljqUYivM/fkuOr3kfXiSN@08TUvumnfrY@y0geJrXXUpilqYqtYVB6LNEkxIfdIU@ywhxoV0rwywsRxLDC8fQCl4hMmOBvISrndAEpv3oMHNgXeMZXmwXM/kKtBxK8D5dIIOPAkxNHbk0tC42xO2H5VEkhnwRKSDaHer2on@XMcf "Curry (PAKCS) ‚Äì Try It Online")
[Answer]
# Python3, 124 bytes:
```
import re
def f(s):
 while'('in s:
  s=re.sub('\(\d*\)',lambda x:f'{(S:=x.span())[1]-1}{x.group()[1:-1]}{S[0]}',s)
 return s
```
[Try it online!](https://tio.run/##TVDJbsIwED3XXzHi4hnkRKTQRZHST@iFY4gqR3GKpSyWbVoqxLfTSVNajvO2mTfuK@7HYf3s/OViezf6CN6IxrTQYqBcwOfedkaitAMEHiEU3qThUKPc4a5Z7kiqTvd1o@GYt/KE27w4psHpAYnKrEqy8@mYvvvx4JDnPMmq82lbrqqzVIEEL4sHz9HX5TpEEYrFYoEEyQuUmYJVJZCQ4/4ABQ8KNgrWCu5/SMJbcoJnCZOTcSb/PQp@Y@fcmX66Eo838SziW0Q7erDAL2htF43H13EwCgL37GzkTwyS@Fd3WtVQgL3CU6wkhkMwXK1c9tqhHaJqURNVRTG1TVlqvO7ezIfusCbhPEtQRhNiADd5G0mXbw)
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 34 bytes
```
‚âî‚ü¶‚üßŒ∑Ôº¶Œ∏¬ø‚Åº(Œπ¬´‚äûœÖÔº¨Œ∑‚äûŒ∑‚Å∞¬ª¬´¬ß‚âîŒ∑‚åàœÖÔº¨Œ∑‚äûŒ∑‚äüœÖ¬ªÔº©Œ∑
```
[Try it online!](https://tio.run/##dYwxC8IwFIRn8ysend6DCO5ORRwEheziEGraBNKkbRIpiL89JnYWbrn77q7Tcum8tDm3IZjB4f3BQdOR9X4BnAlMD3iek7QBG2w4GCJ4s51IQWPicFVuiBo1lckWag6HYj6gbFC1uh238eKeaq34JlczphET/dkLPxVYT5hYjIt4kiH@OjkjUhFR3r/sFw "Charcoal ‚Äì Try It Online") Link is to verbose version of code. Explanation:
```
‚âî‚ü¶‚üßŒ∑
```
Start building up the output list. (I need a second list as I want to use the predefined empty list as a stack.)
```
Ôº¶Œ∏
```
Loop over the input characters.
```
¬ø‚Åº(Œπ¬´
```
If this is a `(`, then...
```
‚äûœÖÔº¨Œ∑
```
... save the current index to the stack, and...
```
‚äûŒ∑‚Å∞
```
... push a dummy value to the output list.
```
¬ª¬´
```
Otherwise, ...
```
¬ß‚âîŒ∑‚åàœÖÔº¨Œ∑
```
... replace the latest dummy value with the current index, and...
```
‚äûŒ∑‚äüœÖ
```
... push its index to the output list, removing it from the stack.
```
¬ªÔº©Œ∑
```
Output the final list of indices.
[Answer]
# [BQN](https://mlochbaum.github.io/BQN/), 24 [bytes](https://github.com/mlochbaum/BQN/blob/master/commentary/sbcs.bqn)
```
(‚ä¢‚äî‚Åº‚ä¢(‚äî‚äíÀú¬®√ó‚ãà¬¨‚ä∏√ó)¬∑+`¬¨-¬ª)‚äê
```
[Try it here.](https://mlochbaum.github.io/BQN/try.html#code=RiDihpAgKOKKouKKlOKBvOKKoijiipTiipLLnMKow5fii4jCrOKKuMOXKcK3K2DCrC3CuyniipAKRsKoIOKfqCIoKSIsIigpKCgpKSIsIigpKCkoKSIsIigoKCkpKSIsIigoKSgoKSkpIuKfqQ==)
How it works [(with example)](https://mlochbaum.github.io/BQN/try.html#code=IyAo4oqi4oqU4oG84oqiKOKKlOKKksucwqjDl+KLiMKs4oq4w5cpwrcrYMKsLcK7KeKKkAoK4oCiU2hvdyAiSW5wdXQ6IiAgICDii4ggICBpIOKGkCAiKCgpKCgpKSkiCuKAolNob3cgIk1hc2s6IiAgIDziirjiiL4gICBtYXNrIOKGkCDiipBpCuKAolNob3cgIkRlcHRoOiIgIDziirjiiL4gICBkIOKGkCAoK2DCrC3CuyltYXNrCuKAolNob3cgIlNwbGl0OiIgIDziirjiiL7ijL0gICAgICBtYXNrKCAgICDDl+KLiMKs4oq4w5cpZArigKJTaG93ICJNYXRjaDoiICA84oq44oi+ICAgcCDihpAgbWFzayjiipTiipLLnMKow5fii4jCrOKKuMOXKWQK4oCiU2hvdyAiQ29tYmluZToiPOKKuOKIviAgIG1hc2sg4oqU4oG8IHAKQA==):
1. Calculate the parenthesis depths from a mask of the string.
2. Split the depths into one vector where the indices of open parens are replaced with 0, and one vector where the indices of close parens are 0, such that if you add them together you get back the original depths.
3. Match depths of the open parens in the close paren half of the depth vector, and close parens in the open paren half, [without repeats](https://mlochbaum.github.io/BQN/doc/search.html#progressive-index-of).
4. Use the original mask to combine the two lists of indices back together.
Detailed breakdown:
```
(‚ä¢‚äî‚Åº‚ä¢(‚äî‚äíÀú¬®√ó‚ãà¬¨‚ä∏√ó)¬∑+`¬¨-¬ª)‚äê  # 
                       ‚äê  # Classify the string to get a mask
(               ¬∑+`¬¨-¬ª)   # Generate depths of parentheses
    ‚ä¢(    √ó‚ãà¬¨‚ä∏√ó)          # Pair mask and it's negation, multiplied by the depths
      ‚äî                   # Group depths according to the mask
       ‚äíÀú                 # Take the progressive index-of
         ¬®                #   between corresponding groups and depths 
  ‚äî‚Åº                      # Inverse partition to combine results
 ‚ä¢                        #   according to the original mask
```
]