[Question]
  [
> 
> [Brain-flak](https://github.com/DJMcMayhem/Brain-Flak) turns one year old tomorrow! In honor of it's birthday, we're having a PPCG style birthday party, where several users post brain-flak related questions! [Help us celebrate!](https://hackmd.io/KwRgnARiAcCGAsBaaEBMAGR8DG8Cmis0AZsVhPLOtsWAOzQAmIQA?view) :)
> 
> 
> 
---
Brain-flak is an esoteric language I wrote where all of the commands are brackets and all of the brackets must be fully matched. To borrow [my own definition](https://codegolf.stackexchange.com/q/77138/31716):
* For the purpose of this challenge, a "bracket" is any of these characters: `()[]{}<>`.
* A pair of brackets is considered "matched" if the opening and closing brackets are in the right order and have no characters inside of them, such as
```
()
[]{}
```
Or if every subelement inside of it is also matched.
```
[()()()()]
{<[]>}
(()())
```
Subelements can also be nested several layers deep.
```
[(){<><>[()]}<>()]
<[{((()))}]>
```
* A string is considered "Fully matched" if and only if:
	1. Every single character is a bracket,
	2. Each pair of brackets has the correct opening and closing bracket and in the right order
In celebration of brain-flak's first birthday, today's challenge is about taking an unbalanced set of brackets, and determining what types of operations are needed to make it valid brain-flak.
* For example, `((` is not valid brain-flak code, but if we append `))` to it, it becomes `(())`, which is fully balanced, and therefore valid brain-flak. That makes this input *appendable*.
* Similarly, `>}` is not valid, but we can prepend `{<` to it to make `{<>}`, which is valid. That makes this input *prependable*.
* Some inputs are slightly more complicated. For example, `)][({` cannot be made valid purely by appending or prepending. But it *can* be made valid by prepending `[(` and appending `})]`. Therefore, this input is both *prependable* and *appendable*.
* Lastly, some inputs can never be made valid brain-flak code by any combination of appending or prepending. For example, `(>` can never be made valid. (Prepending `<` creates `<(>`, and appending `)` creates `(>)`, neither of which are valid) Therefore, this input is neither appendable or prependable.
For today's challenge, you must write a program or function that takes a string of brackets and determines if the string is
```
appendable
prependable
both
neither
```
You may pick what values you use to represent for each case. For example, outputting `1, 2, 3, 4`, or `'a', 'p', 'b', 'n'`, or `1, 'foo', 3.1415, -17`, or whatever is fine. As long as each output is *distinct* and *consistent*, that's fine. You *must* however, clearly specify which output corresponds to which case.
You may return this value in whichever format is most convenient (for example, returning from a function, printing to STDOUT, modifying arguments, writing to a file, etc.).
You can assume that the input will never be valid brain-flak or empty.
# Examples
The following inputs are all *prependable*:
```
))
(((()()())))}
)>}]
()[]{}<>)
```
These are all *appendable*:
```
(({}{})
((((
([]()())(
{<<{
```
These are all *both*:
```
))((
>()[(()){
>{
```
And these are all *neither*:
```
)(}
{(((()()()))>
[}
((((((((((>
((((((((((<>()]
```
As usual, this is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so standard loopholes apply, and the shortest answer in bytes wins!
---
This challenge is particularly difficult in brain-flak, so maximum [brownie points](https://en.wikipedia.org/wiki/Brownie_points) to any and every answer written in brain-flak. :)
  
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~33 32 37 35~~ 34 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
*bug found, horrible fix +5 bytes, better fix - 2 bytes, using a trick of Adnan's I saw [here](https://codegolf.stackexchange.com/questions/117996/find-the-first-bracket-match#comment289022_118011) for -1 more.*
```
“({[<“)}]>”Z;@WœṣF¥/µÐLO‘&2µIṀ>0ȯQ
```
Return values:
```
prepends [2]
 appends [0]
    both [2,0]
 neither 1
```
(Invalid input returns spurious results, although valid Brain-flack, returns `[]`.)
**[Try it online!](https://tio.run/nexus/jelly#@/@oYY5GdbQNkNKsjbV71DA3ytoh/OjkhzsXux1aqn9o6@EJPv6PGmaoGR3a6vlwZ4OdwYn1gf@BynRTTyx/1LjjxPrD7VwPd2853P6oaU3k//@6ugoFRakFqXkpxVyamlwaQKAJgkBQy6VpVxvLpaEZHVtda2OnyQVUm1gAUaqhUV1bXQtRz6URHQvWosFVbWNTDVKWlF@SATQOKGcH1A40UrOay65aA2xEXmpmSUZqEZemRi1XNZJ9dlzRtWDzIMAOiW0DNAXokNhoTa5Ym9hqDQA)** - a test suite (prints mushed representations, so `20` for `[2,0]`, and ignores lines containing any `-`).
[Answer]
# [Retina](https://github.com/m-ender/retina), ~~41~~ ~~40~~ 41 bytes
*1 byte saved thanks to @MartinEnder*
```
+`\(\)|\[]|{}|<>
[]})>]+
1
\W+
0
...+
01
```
[Try it online!](https://tio.run/nexus/retina#TYxBCgMxCEX3/x4FJRA6@@C2R@jCCHMP49nT35nNfBFFH@8ln3O3c8rUNT1W1hoGeJRaNByY34Y3eu8cx96qEEb/xRTUKiDqkTVMwW9W1k1BPC5QkGMkwE1gpGnQhPEk4QpNYnSx86E3eF2iO/bYBy3xAw "Retina – TIO Nexus")
* Prependable is `1`
* Appendable is `0`
* Both is `10`
* None is `01`
### Edits
* Gained 1 byte to fix bug noticed by @Neil
[Answer]
## Batch, 337 bytes
```
@echo off
set/ps=
:g
set "t=%s:<>=%
set "t=%t:()=%
set "t=%t:[]=%
set "t=%t:{}=%
if not "%t%"=="%s%" set "s=%t%"&goto g
set "s=%s:<=[%
set s=%s:>=]%
set s=%s:(=[%
set s=%s:)=]%
set s=%s:{=[%
set s=%s:}=]%
:l
if %s:~,2%==]] set s=%s:~1%&goto l
:r
if %s:~-2%==[[ set s=%s:~,-1%&goto l
if not _%s:~2%==_ set s=[]
echo %s%
```
Outputs `]` for prepend, `[` for append, `][` for both, `[]` for neither.
[Answer]
# [Haskell](https://www.haskell.org/), ~~115~~ 108 bytes
EDIT:
* -7 bytes: Use more guards.
```
(""#)
s#""=[s>"",1>0]
s#(c:d)|Just a<-lookup c$zip"([{<"")]}>"=(a:s)#d|(a:b)<-s=[1|a==c]>>b#d|0<1=take 1$s#d
```
[Try it online!](https://tio.run/nexus/haskell#TUxBjoMwDLz7FchwsKUtKtcq8QP2C1EOKaVa1BZQA1ppQ97OuvTS8cEz4xk/Qj/Yfpi7Z2jnahnu/dDF@hEmij/jb33lene2qyXEkiGWiNZFQfxq5OhVU3u68Pq9xLkI5nAfx9syFW31109ILhlE9lnQUjhFLi@r7jObQ7SuWYO1rRc5q300jZ3DrSuaKpaXbWMGUvBrFBlYsgdi51M28jqmnPI7BOT8niNIxiRQQiCa1T4nEHUoQ/r4J@DyXn1DPrjRood/ "Haskell – TIO Nexus")
Use like `(""#) "))"`. Results are given as:
```
[False,True]: needs nothing
[False]: prependable
[True,True]: appendable
[True]: both
[]: neither
```
# How it works
* The output encoding is chosen such that a need to prepend is signaled by dropping the second element of the result for the remainder, if any, while a complete mismatch is signaled by dropping all of them.
* `s#d` parses a remaining string `d`, given a string/stack `s` of expected closing brackets.
	+ The `s#""` line checks if all closing brackets have been found by the end of the string, otherwise appending is needed.
	+ The first branch of `s#(c:d)` checks if the next character `c` is an opening bracket, and if so leaves the corresponding closing bracket on the stack for the recursion.
	+ Otherwise, if the stack contains closing brackets, the second branch checks if the top one matches the next character, and if not, returns an empty list instead of recursing.
	+ Lastly, in the last branch the stack is empty, and we have an unmatched closing bracket that may be fixed by prepending, before recursing.
[Answer]
# [Japt](https://github.com/ETHproductions/japt), 44 bytes
```
=Ue"%(%)|%[]|\{}|<>" ®c -1&2|1})f31 |UfD |Ug
```
Outputs `1` for prependable, `3` for appendable, `13` for both, and `31` for neither.
[Test it online!](http://ethproductions.github.io/japt/?v=1.4.4&code=PVVlIiUoJSl8JVtdfFx7fXw8PiIgrmMgLTEmMnwxfSlmMzEgfFVmRCB8VWc=&input=IigoKCgoKCgoKCg8PigpXSI=) or [Verify all test cases at once.](http://ethproductions.github.io/japt/?v=1.4.4&code=PVVlIiUoJSl8JVtdfFx7fXw8PiIgrmMgLTEmMnwxfSlmMzEgfFVmRCB8VWc=&input=WwogICIpKSIKICAiKCgoKCkoKSgpKSkpfSIKICAiKT59IgogICIoKVtde308PikiCgogICIoKHt9e30pIgogICIoKCgoIgogICIoW10oKSgpKSgiCiAgIns8PHsiCgogICIpKSgoIgogICI+KClbKCgpKXsiCiAgIj5deyIKCiAgIikofSIKICAieygoKCgpKCkoKSkpPiIKICAiW30iCiAgIigoKCgoKCgoKCg+IgogICIoKCgoKCgoKCgoPD4oKV0iCl0gLW0=)
### How it works
```
 =Ue"%(%)|%[]|\{}|<>" ®   c -1&2|1})f31 |UfD |Ug
U=Ue"%(%)|%[]|\{}|<>" mZ{Zc -1&2|1})f31 |UfD |Ug
                    // "(((()()())))}"  "([({}{})"    ">()[(()){"  "((((<>()]"
Ue"%(%)|%[]|\{}|<>" // Recursively remove all instances of "()", "[]", "{}", and "<>" from U.
                    // "}"              "(["          ">[{"        "((((]"
mZ{Zc -1&2|1}       // Replace each char Z with (Z.charCodeAt() - 1) & 2 | 1.
                    // "1"              "33"          "133"        "33331"
U=                  // Save the result in U.
f31 |UfD |Ug        // Match all instances of "31" and "13" (D = 13) and bitwise-OR the results with the first char.
                    // null|null|1      null|null|3   null|13|1    31|null|3
                    // 1                3             13           31
                    // Implicit: output result of last expression
```
[Answer]
# PHP, 137 Bytes
```
for($c=1;$c;)$a=preg_replace("#<>|\(\)|\[\]|\{\}#","",$a=&$argn,-1,$c);echo($a=preg_replace(["#[]})>]+#","#[[{(<]+#"],[1,2],$a))<13?$a:0;
```
1 =>appendable,
2 =>prependable,
12=>both,
0 =>neither
[Testcases](http://sandbox.onlinephpfunctions.com/code/dd0cd30cf376d398620fc72d3f4259e2a15db5df)
]