[Question]
  [
**This challenge was posted as part of the [April 2018 LotM challenge](https://codegolf.meta.stackexchange.com/q/16116/31716), as well as for Brain-flak's 2nd birthday**
---
I was thinking about what the most efficient way to encode brain-flak programs would be. The obvious thing to do, since there are only 8 valid characters, is to map each character to a 3-bit sequence. This is certainly very effective, but it's still very redundant. There are some features of brain-flak code that we could take advantage of to shorten the encoding. 
* The nilads, which are all represented by 2 matched brackets, really act as a single unit of information rather than 2. If we replaced each bracket with a single byte character, this would make the encodings much smaller without losing any data.
* This one is less obvious, but the *closing bytes* of the monads are redundant too. Think you could guess what the `'?'` characters represent in the following snippet?
```
 {(({}?<>?<>?
```
If we assume the input is valid brain-flak code, then there is only one option for each of those question marks. This means that we can unambiguously use a *close monad* character to represent every closing bracket. This has the added benefit of keeping the character set small, which would greatly help if we wanted to use a huffman encoding. Since the *close monad* character will most likely be the most common character by a wide margin, it could be represent by a single bit, which is hugely efficient.
These two tricks will let us compress brain-flak code via the following algorithm:
1. Replace every closing bracket of a monad with `|`. Or in other words, replace every closing bracket that **is not** preceded by it's opening match with a bar. So...
```
(({})<(()()())>{})
```
would become
```
(({}|<(()()()||{}|
```
2. Replace every nilad with it's closing bracket. Therefore, matched brackets with nothing in them use the following mapping:
```
() --> )
{} --> }
[] --> ]
<> --> >
```
Now our last example becomes:
```
((}|<()))||}|
```
3. Remove trailing `|` characters. Because we know that the total number of bars should equal the total number of `({[<` characters, if there are bars at the end missing, we can infer them. So an example like:
```
({({})({}[()])})
```
would become
```
({(}|(}[)
```
Your challenge for today is to reverse this process.
Given a string of compressed brain-flak containing only the characters `(){}[]<>|`, expand it into the original brain-flak code. You can assume that the input will always expand to valid brain-flak. This means that no prefix of the input will ever contain more `|` than `({[<` characters.
The input will not contain trailing `|` characters. These must be inferred from context.
As usual, you can submit either a full program or a function, and input/output formats are permissive. And since this is a [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), your code will be scored by the length of the source code in bytes, the smaller the score the better.
### Test cases
Here are some test cases. If you would like more, you can generate your own test cases with [this python script](https://tio.run/##bYzBCsIwEETv@YqQS3dRCupNbH@k6aFgioE0DUlEpJtvr0nVkw4sO7ydHfeMt9me1lVPbvaRe8XYEOcp8Cb7etT2OhgDQoJEWhLJTvZ0aUkCFUCFUEHUij3X1t0jIDKrHrlACDbOnpe@fNp2ODOepUdulIVCkDcNP75xUXndNVu4O/QbVibnvy0CU9@Kn7wg8ckG9beMMee1jZBR7UP02kFFFeK6wgJLwjwdYI8p@xc) and [the Brain-Flak Wiki](https://github.com/DJMcMayhem/Brain-Flak/wiki), which is where the majority of these test cases come from.
```
#Compressed code
#Original code
())))
(()()()())
([([}()||||(>||{(})|>|}{((<}|||>}|}>}
([([{}(())])](<>)){({}())<>}{}{((<{}>))<>{}}{}<>{}
({(}|(}[)|||}
({({})({}[()])}{})
(((()))||(](((}}||(}([(((}))||||(]((}}|}|}}|||]||]|[))||(}))|}(}|(}]]|}
((((()()()))([]((({}{}))({}([((({}()())))]([](({}{}){}){}{})))[]))[])[()()])({}()()){}({})({}[][]){}
```
  
[Answer]
# [Brain-Flak](https://github.com/DJMcMayhem/Brain-Flak), ~~952 916~~ 818 bytes
```
{(({})[(((()()()()()){}){}){}])((){[()](<{}>)}{}){{}(({})()<>)(<>)}{}(<>)<>(({})[(((()()()){}){}()){({}[()])}{}])((){[()](<{}>)}{})({}<>{})<>(({})[((((()()()()()){}){})){}{}])((){[()](<{}>)}{})({}<>{})<>(({})[(((((()()()()()){}){}){}())){}{}])((){[()](<{}>)}{})({}<>{}){{}(<(<>({})()()<>)>)}{}<>(({})[(((()()()()()){}){}){}()])((){[()](<{}>)}{}){{}(({})[()])(<>)<>(<({}<{({}<>)<>}{}>)>)<>{({}<>)<>}{}(<>)}{}(<>)<>(({})[(((((()()()()()){})){}{}())){}{}])((){[()](<{}>)}{})({}<>{})<>(({})[((((()()()()()){}){})()){}{}])((){[()](<{}>)}{})({}<>{})<>(({})[(((((()()()()()){}){}){}())()){}{}])((){[()](<{}>)}{})({}<>{}){{}<>(<(({})[()()])(<>)<>(<({}<{({}<>)<>}{}>)>)<>{({}<>)<>}{}>)}{}<>(({})[(((((()()()()()){}){})()){}{}){}])((){[()](<{}>)}{}){{}{}(<(<>{}<>)>)}{}(<>)<>(<({}<{({}<>)<>}{}>)>)<>{({}<>)<>}{}<>}{}{({}<>)<>}<>
```
Saved 360 bytes by calculating opposing brackets relatively rather than from scratch (e.g. `')'` = `'(' + 1` instead of `(((5 * 2) * 2) * 2) + 1`)
Saved 34 bytes with some direct replacements from DJMcMayhem
Saved 10 bytes by overlapping the `>]}` handling code
Saved 118 bytes by deduplicating rolls
Saved 40 bytes by taking advantage of the empty stack to simplify the first roll
Saved 48 bytes by marking EOF with -1, enabling more concise roll code
Saved 36 bytes by using the [stock equals logic](https://github.com/DJMcMayhem/Brain-Flak/wiki/Comparisons) instead of my own
Saved 98 bytes thanks to Jo King finding a more efficient way to build the output
[Try it online!](https://tio.run/##rZLdDoMgDIVfp73wDRpexHjhlixZtuzC29JnZ21lGQFxmsw/4Ainfgcvy3x/Dbfn/EiJAVhwBD3wc6Iqfk2oKo@AExBLQDGVxZcAUkAgF62hUDmtFtaqbh42c8tRX1PQtnRoPkbvE6s3WLT708PYSGFWPif0CQ1b5byXk5PngMgKsVfTodhU65RKJ9GqrpMcIdrNFP6SKhzK1elzHucSaXagC9L/Y/O@ummZ74Hy/vgKFFICBokgI8YYJQ3XNw "Brain-Flak – Try It Online")
First time golfing in Brain-Flak, so there are probably some really big improvements, but it works. Lots of copy/paste to handle each bracket type, and big thanks to the [automatic integer generator](https://brain-flak.github.io/integer/) and the Roll snippet from [here](https://github.com/DJMcMayhem/Brain-Flak/wiki/Stack-Operations).
Explanation [here](https://tio.run/##rVXBbpwwED3DV4zgUFtppH6Ai9RDpUZqo6o9Ig4O6zRWWEBeS21l/O10xrBZJ@xmQxMDwozNzPN7z3BjpG4vbxt5P44umVv@DYPwtev6NE0egl9ku2kUdL1qdfsLboys75XdpQljzvOSYeP7g2MknBXHqCsZr5hwvuAeo3O@q1to1R8L9Z00oHeQsQyrOedDPsZFwZkIbxwwwE/bGQUZzxAZjYoiiVoOVm17@Agf0gWsCQ/dMU6AKPNJeEt0JaHDV0WBc@KyU9GLi7jiggm81pEhVpU7wjx2ny@6rOnimscqJrNAIuYc0wTWC2Qdn1GVSb@g4FK6KnufFRl0BjJP9QIiURxx2rVu5OaMv0jHl5PKY4cFD0weYoJW7cLS8dFTHurEkciLOXw3CrfBJnj2jBFPyxTk@Q@Zqlc5ka33YvEGXmSrl@nPujFqk66k5HPWnGVfJ/wTxUv0r5j86yL/Eoalheum2536WJ6Uhp@hSdt3SM8we5mcyYgjQdAffy1/qL6RtYLf2t6BhB3twM0ezINxX0LCQfX8eq@SrK0yaRqVzD8jQ9HP45Dhyfb41PfNXzBqi3OJnyVPj6ZfbftG19pCb3RrxzGQx/kwsAp73mPHMyLVU3AKYxQPHBoqOsswncY989ipqsGPl/U/), TIO formats it more easily
Bonus answer:
# [Compressed Brain-Flak](https://codegolf.stackexchange.com/q/161056/71434) 583 bytes
```
{((}|[((()))))|}|}|}||(){[)|(<}|||}|{}((}|)>|(>||}(>|>((}|[((()))|}|})|{(}[)|||}||(){[)|(<}|||}|(}>}|>((}|[(((()))))|}|}||}}||(){[)|(<}|||}|(}>}|>((}|[((((()))))|}|}|})||}}||(){[)|(<}|||}|(}>}|{}(<(>(}|))>||||}>((}|[((()))))|}|}|})||(){[)|(<}|||}|{}((}|[)||(>|>(<(}<{(}>|>|}||||>{(}>|>|}(>||}(>|>((}|[((((()))))|}||}})||}}||(){[)|(<}|||}|(}>}|>((}|[(((()))))|}|}|)|}}||(){[)|(<}|||}|(}>}|>((}|[((((()))))|}|}|})|)|}}||(){[)|(<}|||}|(}>}|{}>(<((}|[))||(>|>(<(}<{(}>|>|}||||>{(}>|>|}|||}>((}|[((((()))))|}|}|)|}}|}||(){[)|(<}|||}|{}}(<(>}>||||}(>|>(<(}<{(}>|>|}||||>{(}>|>|}>|}{(}>|>|>
```
[Try it online!](https://tio.run/##lZFNDoJADIWv87rgBpNehMwCTUyMxoXbac8@9g0YMIAoTEjb6c/3yuk5XB/d5T7cai2AWw9A@Ji31yClF0MKM9ziTBI1aLjx0UURC8QKPApsXQtXn/MXU8yPcpdIspsfcAlKvgBkWDcUybYkIjc5CZ5CQpgkM9O3s1I8tw0g@UHFTCH/SpZ9zURuAg4VfKxkhbPxr9s@fdzl99ZxJlNrnZpHvxxWA3dwpjM4httAXlnmGel576CynM1rd34B "Brain-Flak – Try It Online")
(Note that the above link does not run because TIO doesn't have a Compressed Brain-Flak interpreter. You can find a transpiler to Brain-Flak [here](https://codegolf.stackexchange.com/q/161056/71434))
I have checked that this is valid by transpiling to Brain-Flak using [this](https://tio.run/##rVNJbsMwDPwOecgPCH4kyCENUKBo0UOuIt/ucGgHVi15A@pNEk0OZ0b2x/P@9Xv5/Ll/D0MhKs5XioPfJ0ckrxtHtFyJbyTFlR3R4llCLMokGcQgukAaITBGHBjI7CHGa9EYa4SGTNwnqjtaYrqLAW0SYkZ9qTATGm0L5C2fUvlkkKBRyW6xdKRiUkdWHF30TSVHFG16Sv/iKh3yNdVPfpxzpNmBVSHrX@y0rwla@3ugfT7mgGj@M26gwjjM8zT0ZSOJaSyx@26sRhrLeGhVhAK2Qh4F1taSq8/5VRfzvdyaEq/mpx0KfkEQYe0o4r4kUE45QrDOYwpmZvpeNIpn2CDEB1TMLPisZF7XnF8gBOwq@GNJQ6ez1@mnj15uQ8c1TXW4PF4) tool, now efficient enough that timing out is unlikely.
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), ~~103~~ 98 bytes
```
[])}>]
$&;
T`])}>|`[({<;
r`(.*)((;)|(?<-3>.))*
$&$.1$*;
(?<=(.)((;)|(?<-3>.))*);
;$1
T`;-{`_>-}`;.
```
[Try it online!](https://tio.run/##XYyxDsIwDET3fEeEzpUaqWJ0CT/BFkWEgYGFoWKL/e3lUjYuGc7n89uen9f7se@liuca4knDrQ1vraCvGraGNAmgYriu8zknkYm9mJY4aWB2QfrfiwaNC0k693bPszdN@w6hAgqKQ4xCNutwsWzegdWZZTfPHsDc4GX0OFG85UWlc/bg5NDKD1SPlG8g6vjlqI@9H6Razb8 "Retina 0.8.2 – Try It Online") Link includes test cases. Edit: Saved 5 bytes with inspiration from @MartinEnder. Explanation:
```
[])}>]
$&;
T`])}>|`[({<;
```
Put a `;` after every close bracket and change them all to open brackets, and change the `|`s to `;`s too.
```
r`(.*)((;)|(?<-3>.))*
$&$.1$*;
```
Count the number of unmatched open brackets and add that many `;`s.
```
(?<=(.)((;)|(?<-3>.))*);
;$1
```
Copy each opening bracket to its matching `;`.
```
T`;-{`_>-}`;.
```
Flip the copied brackets and delete the `;`s.
[Answer]
# [TIS](https://github.com/Phlarx/tis.git), ~~670~~ 666 bytes
-4 bytes for jumping forward to jump back
Code:
```
@0
MOV UP RIGHT
@1
MOV ANY ACC
SUB 41
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
MOV ACC DOWN
@2
NOP
MOV 124 LEFT
@3
MOV ANY DOWN
@4
MOV UP ACC
JGZ O
MOV 40 LEFT
JLZ (
MOV 41 LEFT
JRO 3
O:SUB 21
MOV ACC DOWN
JRO -8
(:MOV 41 RIGHT
@5
MOV ANY DOWN
@6
MOV ANY DOWN
@7
MOV UP ACC
JGZ O
MOV 60 LEFT
JLZ <
MOV 62 LEFT
JRO 3
O:SUB 31
MOV ACC DOWN
JRO -8
<:MOV 62 RIGHT
@8
MOV ANY DOWN
@9
MOV ANY DOWN
@10
S:MOV UP ACC
JGZ O
MOV 91 LEFT
JLZ [
MOV 93 LEFT
JRO 3
O:SUB 31
MOV ACC DOWN
JRO -8
[:MOV 93 RIGHT
@11
MOV ANY DOWN
@12
MOV ANY DOWN
@13
MOV UP ACC
JEZ |
MOV 123 LEFT
JLZ {
MOV 125 LEFT
JRO 2
|:MOV DOWN LEFT
JRO -7
{:MOV 125 RIGHT
@14
MOV ANY DOWN
@15
MOV UP DOWN
@16
MOV UP LEFT
```
Layout:
```
6 3
CCCCCCCCCCCCCCCCSC
I0 ASCII -
O0 ASCII -
```
[Try it online!](https://tio.run/##jZHfToMwFMbvz1OcS7wgoX9gW0MMWOdkmXQZTiPEBzDxTu/AZ6@Dtmx0xHjRpN/Xc873a/v98aV1FsGTesHjHg/F5vEZMjLovHzDXEqojnfICZRq/@caWqTEe/VaQkZHj1COu/XDaSwbx5oa7mL7lO2mRjUYPDL1212NgXGIdQ4KwxiU6JEomUYOh0sIhO2wd4m90MTTi3mI5AIiNQ6dgWDzEKmwHRZi6YWuPE0iqMQsx4qcORrjsP9zNMJ2uI8lfjD1DTZ5j3WNnf1FdgZprRVPSLohrB9zYS@gFa7YQXA/M3aZVidO93O0TtsmuHn/6W51@KkTZCBP17xalYQiwrySRYEhqHH7Cw "TIS – Try It Online")
I doubt this is smallest, but I don't see a way to make it smaller. Unfortunately, all the `NOP`s seem necessary for timing, and I can't put the stack where `@14` currently is because of the read from `ANY` in `@11`.
The structure of this solution is as follows:
```
Input
  |
  V
  0    1:synchro  2:EOF
  3    4:parens     5
  6    7:angles     8
  9   10:squares   11
 12   13:curlies   14
 15      stack     16
  |
  V
Output
```
Upon seeing an open brace, the open is sent along the left column to be output, and the close is sent along the right column to the stack.
Upon seeing a close brace, the open and close are both sent along the left column to be output.
Upon seeing a pipe, the stack is popped and sent to output.
Upon EOF, `@1` will begin reading from `@2`, instead of the input stream from `@0`. `@2` produces an endless stream of pipes, so the stack will be drained.
Once both the input and the stack are exhausted, the program halts.
Warning: due to the limitations of TIS, the stack size is limited to 15. If anything is nested deeper than that, this implementation will produce an incorrect result.
[Answer]
# JavaScript (ES6), 107 bytes
Takes input as an array of characters. Returns a string.
```
a=>a.map(c=>(n=(S='|()[]{}<>').indexOf(c))?n&1?(s=[S[n+1],...s],c):S[n-1]+c:s.shift(),s=[]).join``+s.join``
```
[Try it online!](https://tio.run/##dU5BbsIwELz3GRzKrBIs5YqweUIPHK2ViEzSBlEb1ahCivftYRN6LOM9jHdnZ/bc/rY5/AzX2yamUzf1dmqta813e0WwDtHiYNcF5HmUnVuTGeKpu3/0CET7@N7ska0/@Fg1XBtjMteBtvrfNFyFbTb5a@hvoFpVTOachng8VvmPTCHFnC6duaRP9PBqsAIpVkz09t/QwwuoKOBKGSFUXJER2In2nBRx8nJZ5QXi5/XXIoUeoP6sTNQVoqlK6RnLS1ffHMhz@UU@z2UJYH7aTw8 "JavaScript (Node.js) – Try It Online")
[Answer]
# [Brain-Flak](https://github.com/Flakheads/BrainHack), ~~606 548 496 418 394~~ 390 bytes
```
{((({})))(<>)(((((((([(())()()()]){}){}){}())(()))(((())()())()){}{})){}[()])({<(({}<>{}[()]))>(){[()](<{}>)}{}<>}{}<><{}>){({}({})<>)(<>)}{}({}<>)(<>)(((((((([(())()()()]){}){}){}())(()))(((())()){}()){})){})({<(({}<>{}[()]))>[()]{()(<{}>)}{}<>}{}<>){(<({}(<()>)<>({})<{({}<>)<>}>)>)<>{({}<>)<>}}{}({}()<>){{}({}<>)((<>))}{}{}<>(<({}(<()>)<><{({}<>)<>}>)>)<>{({}<>)<>}{}<>}{}{({}{}<>)<>}<>
```
[Try it online!](https://tio.run/##lVFBbsNACPxLTnDIDxBS32H1kOaSqlIOuQJv386wdt1EUaraqzUM7Myw/ridPq@X0/lrjBCRKFUVc5X1WUQA9PuuqPYiJGyUrcoVxdNRC1sljGzma64uGozEolyLpd46DbRSm8LW1T77fycTmj6eeOAnwPDgAfpGBybq8NBOYjpAhze459Od0Gz8GKVTMjK7I3tBtOoT2CDzMcYBf6IyxXOfXRNTZhZfTaSsEUzNQnMthDhweceZuG90GopZjsUopEDt5M6iihh6Pf1vJWYUelDBHvpLJXmXNWnBj/GBOTvTtxgeFI3FVGgFI/h@7NkZciPs2A/j@PYN "Brain-Flak (BrainHack) – Try It Online")
I started this by golfing [Kamil Drakari's answer](https://codegolf.stackexchange.com/a/161083/76162), but it got away from me to the point where I decided to post it as a separate answer.
### Explanation:
```
{ #While input on stack
	((({})))(<>)	#Preserve copy of the character
	(((((		#Push the differences between start bracket characters
	((([(())()()()]){}){}){}())	#Push -31, 1
	(()))				#Push -30, 1
	(((())()())()){}{})		#Push -19, 1
	){}[()])			#Push -39
	({<(({}<>{}[()]))>(){[()](<{}>)}{}<>}{}<><{}>)	#If the character is any of the start brackets
	{({}({})<>)(<>)}{}					#Push the current character + TOS to the other stack
	({}<>)(<>)
	(((((		#Push the differences between end bracket characters
	((([(())()()()]){}){}){}())	#Push -31, 1
	(()))				#Push -30, 1
	(((())()){}()){})		#Push -19, 1
	){})				#Push -40
	({<(({}<>{}[()]))>[()]{()(<{}>)}{}<>}{}<>)	#If the character is any of the end brackets
	{(<({}(<()>)<>({})<{({}<>)<>}>)>)<>{({}<>)<>}}{}	#Push the character + TOS to the output
	({}()<>)	#If the character is not a |
	{{}({}<>)((<>))}{}	#Move current character to the other stack and push a zero
	{}		#Pop the top value of the stack, either the | or a 0
	<>(<({}(<()>)<><{({}<>)<>}>)>)<>{({}<>)<>}{}<>	#And push top of other stack to the output
}{}
{({}{}<>)<>}<>	#Reverse output and append the excess end brackets
```
And of course...
# Compressed Brain-Flak, 285 bytes:
```
{(((}|||(>|(((((((([()|)))||}|}|})|()||((()|))|)|}}||}[)||({<((}>}[)||||){[)|(<}|||}>|}><}||{(}(}|>|(>||}(}>|(>|(((((((([()|)))||}|}|})|()||((()|)|})|}||}|({<((}>}[)||||[)|{)(<}|||}>|}>|{(<(}(<)||>(}|<{(}>|>|||||>{(}>|>||}(})>|{}(}>|((>|||}}>(<(}(<)||><{(}>|>|||||>{(}>|>|}>|}{(}}>|>|>
```
[Answer]
## Haskell, ~~127~~ 121 bytes
```
(""#)
(u:t)#('|':b)=u:t#b 
s#(c:b)|elem c")>]}"=m c:c:s#b|q<-m c:s=c:q#b
s#b=b++s
m c="> < ] [)(} {"!!mod(fromEnum c-6)27
```
[Try it online!](https://tio.run/##NYwxU4QwEIV7fsVeUtxmTiwsdIYh6ey0sowZh0Q4HYHjLlCR/evignebFO@9fft9VfGnbtul0fC@oBBSZTgVo5K4T/vCK81GesiixMA21W3dQRDKOBKaVRGKKH06l/lqog7FWXpue@0Ph5hxqIWBEhxYhQSz2O260yc2l1P33E@8zh/Vw9PSVd89aOiq4fUDcJjGt/Hy0sM9NApsBiBwRkpIVom7zSqeq7RoCVXiQZMS91QyiWbEkjgzlMjQtXqDcH6LeBjFt44V8QUSE1mqf6TbUn4rzK3fbvV1TxvOOYa5bPkNTVsd45KHYfgD "Haskell – Try It Online")
Edit: -6 bytes by using @Laikoni's [function to find the matching bracket](https://codegolf.stackexchange.com/a/161087/34531).
[Answer]
# [Ruby](https://www.ruby-lang.org/), 104 bytes
```
a=[];$<.chars{|c|r="|[{(<>)}]";i=r.index(c);i<1||(i<5?a:$>)<<r[-i];$>.<<i<1?a.pop: c};$><<a.reverse.join
```
This is a full program that outputs to the console. `(i<5?a:$>)<<r[-i]` has got to be one of the coolest golfs I have ever done.
[Try it online!](https://tio.run/##DcuxCsMgEIDhVykhgw496JAlnuZBxMFYodchCRcaWjyf3br@Hz9/1l9r0fpgRoT0inwWScJ2EF8UOl3DYMgy0PbMX5W0IXyIKMJpifPoNCL7O/XbAWK3JcKxH/Mt1Z4QI3C@Mp8Z3jttramivJYqon0Q9wc "Ruby – Try It Online")
# [Ruby](https://www.ruby-lang.org/), 106 bytes
```
->s{a=[];(s.chars.map{|c|r="|>)}][{(<";d=r[-i=r.index(c)];i<5||a<<d;i<1?a.pop: i<5?d+c:c}+a.reverse).join}
```
This is my first solution. An anonymous lambda function that takes and returns strings.
[Try it online!](https://tio.run/##JYpBDoIwEEWvQli1ITRx4QZaPEgzi1pKrIlAWjEaZs5eB/0zi5f3f9qunzKZ0g55d8ZCL7LyN5eyerh1R4/J1DhIArsLXfejSbaNJqk4j@EtvIQ@6jOi03pkOl2cWpe1q1hexsZ3nhqnUniFlINU9yXOVNbtmavJ1oIjpUQUwETEQMIeeMi/ZsvHFcLx9jc/ehLEAIBUQ/kC "Ruby – Try It Online")
[Answer]
# Java 10, 424 bytes
```
s->{int i=0;for(var c:s.toCharArray()){if("(<[{".indexOf(c)>-1)i++;if(c=='|')i--;}for(;i-->0;)s+='|';s=s.replace(")","()").replace(">","<>").replace("]","[]").replace("}","{}");char[]c=s.toCharArray(),r=new char[124];r[40]=41;r[60]=62;r[91]=93;r['{']='}';var o="";for(;++i<c.length ;){if(c[i]=='|'){c[i]=o.charAt(0);o=o.substring(1);}if("(<[{".indexOf(c[i])>-1&")>]}".indexOf(i+1<c.length?c[i+1]:0)<0)o=r[c[i]]+o;}return c;}
```
It's kind of lengthy, but I couldn't figure out how to shorten it further.
This is a nice challenge though.
Try it online [here](https://tio.run/##dVRbT9swFH4Ov8Lyw@qjtFG7ISRwkglNe5z2wKPlh5C6YBaSzk47kOPf3h07aWEDcpGPv3P9TnL8UO2rxcP612G7u210Teqmspb8qHRL3Fmi216ZTVUr8v1pW7VrZQKa1PeVEZKoiLGb3uj2jtTd49Yoa9Ua@Fniz5Ipou2rHpd9p9fkEeNO9uhfmTsLMeApujoKBTnYRemwAKKLJd90hu0rQ@orm/XdN8x/bUz1zACc3jDKcuFoptHz6eeG1VAuVqDTlKOuLorZMAO9WHAfonCUyiUHmwac28JmRm0b5Mgo0DllQOEFKRHJy9eIRETI14hHxHkKfGxLXfxX4twUrfpDonb1@VxyI86XsjhfoXCBwsVnFC5Xsrj8gsLMzWQx8zMe6HYFpZE7T1Od11mj2rv@nvDIuhZajuRcFLsspLju2RJ4hzu7u7Wx1WwF3L/TJnQKnfpEoZT@Bdfp6pTqKxqlK3m1hHwJXWFEcJJpx71R/c60pOb@kCT4wZMtpurZ8QPOCWWO@YF5gV2NG@cBX8FAgscmv@8DeEV7BuP9oaVgwjMY8GLlMGAuGMrBO8Zyj1jpB196Ohk6j/Ewr2R5ib8MloHbvPQu2jtfhp3zuA/LRxmPfDC8f4eT@5gVC@nRj0mUPNbHPJaFIowEZETxDqXL8IhoHvQ@ZpVyyhljxcYAEyGcC4lDFTFiYBabKKM2KuMTjEDI@IpgI@FojMvEQ6Jy4h8G2Oh91at/Jnjk9mZe5@TNKXCCbNfset2146hP4OS4xkEPwzGip55l09Hy6kyJnb15tr16zLpdn8VCmvboss7U713VWHbKllJC06N2ZOQPfwE).
Ungolfed version:
```
s -> { // lambda taking a String argument and returning a char[]
    int i = 0; // used for counting the number of '|'s that have been removed at the end of the input
    for(var c : s.toCharArray()) { // look at every character
        if("(<[{".indexOf(c) > -1) // if it's an open monad character
            i++; // we will need one more '|'
        if(c == '|') // if it's a close monad character
            i--; // we will need one '|' less
    }
    for(; i-- > 0; ) // add as many '|'
        s += '|';    // as necessary
    s = s.replace(")", "()").replace(">", "<>").replace("]", "[]").replace("}", "{}"); // replace compressed nilads with their uncompressed versions
    char[] c = s.toCharArray(), // from now on working on a char[] is more efficient since we will only be comparing and replacing
    r = new char[124]; // map open monad characters to their counterparts:
    r[40] = 41;   // '(' to ')'
    r[60] = 62;   // '<' to '>'
    r[91] = 93;   // '[' to ']'
    r['{'] = '}'; // '{' to '}'
    var o = ""; // we use this String as a kind of stack to keep track of the last open monad character we saw
    for(; ++i < c.length ;) { // iterate over the length of the expanded code
        if(c[i] == '|') { // if the current character is a close monad character
            c[i] = o.charAt(0); // replace it with the top of the stack
            o = o.substring(1); // and pop the stack
        }
        if("(<[{".indexOf(c[i]) > -1 // if the current character is an open monad/nilad character
         & ")>]}".indexOf(i+1 < c.length ? c[i+1] : 0) < 0) // and it's not part of a nilad (we need to test for length here to avoid overshooting)
            o = r[c[i]]+o; // using the mapping we established, push the corresponding character onto the stack
    }
    return c; // return the uncompressed code
}
```
[Answer]
# Python 2, ~~188~~ ~~184~~ ~~180~~ ~~177~~ ~~174~~ 173 bytes
```
p,q='([{<',')]}>'
d,s,a=dict(zip(p,q)),[],''
for c in input():
 if c in d:a+=c;s+=[c]
 elif'|'==c:a+=d[s.pop()]
 else:a+=dict(zip(q,p))[c]+c
for c in s[::-1]:a+=d[c]
print a
```
Saved 4 bytes thanks to DJMcMayhem.  
[Try it online!](https://tio.run/##RY7BDoMgEETvfgW33Y20SXukwo8QDwY1JWkUhR5a4dsp1TTdzOntzsy6V7jP0zVnxxcJqLcGOFCbFFQ997yTvTUB39ZhOSDiuuUA1TivzDA7FblnQBIVs@NBetHV0tx8LbVpKzY87AgRpDRf3mt/drND2jd@2NmvYOGOqJhq88/3WojTpT28Jc@tdgqsy7m8ijohxTKoYtwwUVQxbYhNKkylmFSCDw "Python 2 – Try It Online")
[Answer]
# [Python 3](https://docs.python.org/3/), 122 bytes
```
D='()<>[]{} '
def f(x):
 a=s=''
 for c in x:i=D.find(c);a+=i<0and s[0]or D[i-(i&1):i+1];s=D[i+1][i&1:]+s[i<0:]
 return a+s
```
[Try it online!](https://tio.run/##XVHLbuMwDLzrK4QcViSSBi325kY@Bb32A1QejMbGCg3UwHKxKWR@e0rK7SJZPSBxOORQ4ulz@vOefl8ue@8Ad22gwtaZQz/YAc7YGNv57J0zdngf7auNyZ6b6PfbIaYDvOJjt/Zxd9@lg83hnoSzD/EO4q8HbOL6gR6zF0AuQaCG1jkIuyFjx376GJPt1vky9XnK1ttw3uZpjCfAbT4d4wRYRc8qulqtjP03AGVc24DLRHONBggMOMuAdp4LMM7tzAVgx4K1PHPL//ELSy4kJNi1iAXERvkWLjWscKtWYbH1uFGT/DNwUD2@xQuj7ACSVwJvawTVkxggubHUBSx1yBWXwqmiMrVk0hUqXf1cFYlu9WrK@hkIQbMWFdUKamJ9Uf0/qt7qrEtJGKjuoBzCH7Ic328gcZZrOWnMd7fcS3pJ7rotZIw2UPu7sV3Kf/tRe1n73VTe2OeP4yS9H0DRJfg0xjTBErUQNja4py4e3cY9vzkKC@r9kpPQXL4A "Python 3 – Try It Online")
[Answer]
# [Haskell](https://www.haskell.org/), 152 bytes
```
fst.p
m c="> < ] [)(} {"!!mod(fromEnum c-6)27
p(c:r)|elem c")]}>",(s,t)<-p r=(m c:c:s,t)|c/='|',(s,'|':t)<-p$r++"|",(u,v)<-p t=(c:s++m c:u,v)
p e=("",e)
```
[Try it online!](https://tio.run/##JYxBa8MwDIXv@RWqKVQiyQY7bBDqXsbuPRYyH4Jnd2VJGmx3l9p/vZ6cSQI9vqen78H/mHHMVn5m68PTUk2gpTjAHhT0hAnuYrOZrl9o3XX6mG9st6/08lYtqDtH0YyGkSCVDqJB3wTatws4iUw73RUQ9bPcxV1xeXXrxdbVtYicuDW/ayJI/ufrusQKqxYwEoVoDOVpuMwg4TIH4wYdwGbkIqIYUbFKiUXCvsgC/zFTbraiKtOv58VPmFgoFdND23E4@9ye3o/HPw "Haskell – Try It Online") or [verify all test cases](https://tio.run/##NVFNa9wwEL37V0xEIDPY20IPDRjbl9KeUljopaDq4HXkZKm9ayxtKFj6693OzDb6sKQ3b94bya99@O2n6Tq2v65jiB@WYoahNR004MASZtjM3d18fsZxPc9fTxcO7z7Tp8diwaFeKfnJM2TI5c5UGKpIzW6BtUVG66EWIA0f24f0IFFeamXcr2VpEmdcqjfNiC3rhbKUNMGKBXyLxlSertGHGKAFWwAaJG6mMoh062SoAo1YtBkpccMupQ0zpS7lDbHJjHU55S5LJvO2zPnkyGHTEW3IZ6Kmy5vSt9zJact8loUd1IAlE2YrFiokecTTIksxl96JKOpMQ8e7zO6Y2ZW3dCvPKcpdCnMyrNIlntXEuZuFSuk1Ca2obeIjpioodeuLOI1qUIeQyDqdVjiO3sm8/C/bcVBu54pC3hiwrw7ED71c4o@4Pp3gHo4jjNBD28IB4qs/gdn3IRjwU/BgvvXHqQb/Z/FD9M9goCyZxx8Dh0uEl3O8YSxRFHN/PLH43C/fQe30v17/DuPUv4Tr7ueX/f4f "Haskell – Try It Online"). `p` implements a recursive parser, which might be over kill for the simple grammar.
[Answer]
# [Python 2](https://docs.python.org/2/), 244 bytes
```
s=input()
B='([{<'
C=')]}>'
Z=zip(B,C)
P=sum(map(s.count,B))-s.count('|')
for i,j in Z:s=s.replace(j,i+j)
s+=P*'|'
b=[0]
for i in s:[b.pop()for j,k in Z if j==b[-1]<k==i];b+=[i][:i in B];s=i=='|'and s.replace(i,C[B.find(b.pop())],1)or s
print s
```
[Try it online!](https://tio.run/##RY6xcsMgEER7voKOuwhr4pSyL4X0A67NUEi2NUG2ESOkIrb4dgVkzwQo3uzu7eF@x5/efi2LJ2PdNAKykgSo516wigTq8C3YkR7GQSkrZAfy0x3utQOfn/rJjrJE3LwZxCyQtf3Ajey4sfxYePL5cHG3@nSBTpqsQ@YzOnzEJGtIfepXPIV9oZrc9Q4wSZ28rg3ctLwjatRmq/dXIqN3TUbKaFWsU6Xexa8TxcLanvn/NiMrVeatsWd416KWW4zVnrnB2JH7ZREQDyLOM@hIIUQIoBIm8SVHNd5ozTo9tcaTHyBE0HoO4g8 "Python 2 – Try It Online")
It took way more than an hour or two to get this working...
]