This question is the second of several Brain-flak Birthday challenges designed to celebrate Brain-Flak's first Birthday! You can find more information about Brain-Flak's Birthday here
Challenge
For this challenge you'll be generating all fully matched strings from a list of brackets. To borrow DJMcMayhem's definition of a fully matched string:
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 each pair of brackets has the correct opening and closing bracket in the right order.
Input
Your program or function will take a list of four non-negative numbers in any convenient, consistent format. This includes (but is not limited to) a list of integers, a non-digit delimited string, or separate arguments. These four numbers represent the number of matched pairs of each type of bracket. For example, [1,2,3,4] would represent:
1 pair of
()2 pairs of
{}3 pairs of
[]and4 pairs of
<>
You may choose which pair of brackets each input corresponds to as long as it is consistent.
Output
You should output all fully matched string that can be formed from this list of brackets without duplicates. Output can be in any reasonable format which includes printing a non-bracket delimited string to STDOUT, or a list of strings as a return value from a function.
Your algorithm must work for any arbitrary input, but you don't need to worry about memory, time or integer size limits (e.g. if your answer is in C you won't get 233 as an input).
This is code-golf, so the shortest answer in bytes wins.
Example Input and Output
For these example I will use the same input order as above.
For each example, the first line will be input and the following lines will be the output
Example 0:
[0,0,0,0]
Example 1:
[1,0,0,0]
()
Example 2:
[0,2,0,0]
{}{}
{{}}
Example 3:
[0,0,1,1]
[]<>
[<>]
<[]>
<>[]
Example 4:
[0,1,2,0]
{}[][] {}[[]] {[]}[] {[][]} {[[]]}
[{}][] [{}[]] [{[]}] []{}[] []{[]}
[][{}] [][]{} [[{}]] [[]{}] [[]]{}
Example 5:
[1,0,0,3]
()<><><> ()<><<>> ()<<>><> ()<<><>> ()<<<>>> (<>)<><> (<>)<<>>
(<><>)<> (<><><>) (<><<>>) (<<>>)<> (<<>><>) (<<><>>) (<<<>>>)
<()><><> <()><<>> <()<>><> <()<><>> <()<<>>> <(<>)><> <(<>)<>>
<(<><>)> <(<<>>)> <>()<><> <>()<<>> <>(<>)<> <>(<><>) <>(<<>>)
<><()><> <><()<>> <><(<>)> <><>()<> <><>(<>) <><><()> <><><>()
<><<()>> <><<>()> <><<>>() <<()>><> <<()><>> <<()<>>> <<(<>)>>
<<>()><> <<>()<>> <<>(<>)> <<>>()<> <<>>(<>) <<>><()> <<>><>()
<<><()>> <<><>()> <<><>>() <<<()>>> <<<>()>> <<<>>()> <<<>>>()
Example 6:
[1,1,1,1]
(){}[]<> (){}[<>] (){}<[]> (){}<>[] (){[]}<> (){[]<>} (){[<>]}
(){<[]>} (){<>}[] (){<>[]} ()[{}]<> ()[{}<>] ()[{<>}] ()[]{}<>
()[]{<>} ()[]<{}> ()[]<>{} ()[<{}>] ()[<>{}] ()[<>]{} ()<{}[]>
()<{}>[] ()<{[]}> ()<[{}]> ()<[]{}> ()<[]>{} ()<>{}[] ()<>{[]}
()<>[{}] ()<>[]{} ({})[]<> ({})[<>] ({})<[]> ({})<>[] ({}[])<>
({}[]<>) ({}[<>]) ({}<[]>) ({}<>)[] ({}<>[]) ({[]})<> ({[]}<>)
({[]<>}) ({[<>]}) ({<[]>}) ({<>})[] ({<>}[]) ({<>[]}) ([{}])<>
([{}]<>) ([{}<>]) ([{<>}]) ([]){}<> ([]){<>} ([])<{}> ([])<>{}
([]{})<> ([]{}<>) ([]{<>}) ([]<{}>) ([]<>){} ([]<>{}) ([<{}>])
([<>{}]) ([<>]){} ([<>]{}) (<{}[]>) (<{}>)[] (<{}>[]) (<{[]}>)
(<[{}]>) (<[]{}>) (<[]>){} (<[]>{}) (<>){}[] (<>){[]} (<>)[{}]
(<>)[]{} (<>{})[] (<>{}[]) (<>{[]}) (<>[{}]) (<>[]){} (<>[]{})
{()}[]<> {()}[<>] {()}<[]> {()}<>[] {()[]}<> {()[]<>} {()[<>]}
{()<[]>} {()<>}[] {()<>[]} {([])}<> {([])<>} {([]<>)} {([<>])}
{(<[]>)} {(<>)}[] {(<>)[]} {(<>[])} {}()[]<> {}()[<>] {}()<[]>
{}()<>[] {}([])<> {}([]<>) {}([<>]) {}(<[]>) {}(<>)[] {}(<>[])
{}[()]<> {}[()<>] {}[(<>)] {}[]()<> {}[](<>) {}[]<()> {}[]<>()
{}[<()>] {}[<>()] {}[<>]() {}<()[]> {}<()>[] {}<([])> {}<[()]>
{}<[]()> {}<[]>() {}<>()[] {}<>([]) {}<>[()] {}<>[]() {[()]}<>
{[()]<>} {[()<>]} {[(<>)]} {[]()}<> {[]()<>} {[](<>)} {[]}()<>
{[]}(<>) {[]}<()> {[]}<>() {[]<()>} {[]<>()} {[]<>}() {[<()>]}
{[<>()]} {[<>]()} {[<>]}() {<()[]>} {<()>}[] {<()>[]} {<([])>}
{<[()]>} {<[]()>} {<[]>()} {<[]>}() {<>()}[] {<>()[]} {<>([])}
{<>}()[] {<>}([]) {<>}[()] {<>}[]() {<>[()]} {<>[]()} {<>[]}()
[(){}]<> [(){}<>] [(){<>}] [()]{}<> [()]{<>} [()]<{}> [()]<>{}
[()<{}>] [()<>{}] [()<>]{} [({})]<> [({})<>] [({}<>)] [({<>})]
[(<{}>)] [(<>){}] [(<>)]{} [(<>{})] [{()}]<> [{()}<>] [{()<>}]
[{(<>)}] [{}()]<> [{}()<>] [{}(<>)] [{}]()<> [{}](<>) [{}]<()>
[{}]<>() [{}<()>] [{}<>()] [{}<>]() [{<()>}] [{<>()}] [{<>}()]
[{<>}]() [](){}<> [](){<>} []()<{}> []()<>{} []({})<> []({}<>)
[]({<>}) [](<{}>) [](<>){} [](<>{}) []{()}<> []{()<>} []{(<>)}
[]{}()<> []{}(<>) []{}<()> []{}<>() []{<()>} []{<>()} []{<>}()
[]<(){}> []<()>{} []<({})> []<{()}> []<{}()> []<{}>() []<>(){}
[]<>({}) []<>{()} []<>{}() [<(){}>] [<()>{}] [<()>]{} [<({})>]
[<{()}>] [<{}()>] [<{}>()] [<{}>]() [<>(){}] [<>()]{} [<>({})]
[<>{()}] [<>{}()] [<>{}]() [<>](){} [<>]({}) [<>]{()} [<>]{}()
<(){}[]> <(){}>[] <(){[]}> <()[{}]> <()[]{}> <()[]>{} <()>{}[]
<()>{[]} <()>[{}] <()>[]{} <({})[]> <({})>[] <({}[])> <({[]})>
<([{}])> <([]){}> <([])>{} <([]{})> <{()}[]> <{()}>[] <{()[]}>
<{([])}> <{}()[]> <{}()>[] <{}([])> <{}[()]> <{}[]()> <{}[]>()
<{}>()[] <{}>([]) <{}>[()] <{}>[]() <{[()]}> <{[]()}> <{[]}()>
<{[]}>() <[(){}]> <[()]{}> <[()]>{} <[({})]> <[{()}]> <[{}()]>
<[{}]()> <[{}]>() <[](){}> <[]()>{} <[]({})> <[]{()}> <[]{}()>
<[]{}>() <[]>(){} <[]>({}) <[]>{()} <[]>{}() <>(){}[] <>(){[]}
<>()[{}] <>()[]{} <>({})[] <>({}[]) <>({[]}) <>([{}]) <>([]){}
<>([]{}) <>{()}[] <>{()[]} <>{([])} <>{}()[] <>{}([]) <>{}[()]
<>{}[]() <>{[()]} <>{[]()} <>{[]}() <>[(){}] <>[()]{} <>[({})]
<>[{()}] <>[{}()] <>[{}]() <>[](){} <>[]({}) <>[]{()} <>[]{}()
-
\$\begingroup\$ Related \$\endgroup\$Riley– Riley2017年04月27日 18:13:47 +00:00Commented Apr 27, 2017 at 18:13
5 Answers 5
Haskell, 128 bytes
f is the main function, it takes a list of Ints and returns a list of Strings.
f=g.($zip"({[<"")}]>").zipWith replicate
g=max[""].(#g)
l#c=[b:s|x@(b,e):r<-l,s<-(r:filter(/=x:r)l)?(map(e:).c)]
l?c=c l++l#(?c)
How it works
ftransforms its input list into a list of lists of tuples, each tuple containing a bracket pair, with each type of bracket in its own sublist. E.g.[1,2,0,0]becomes[[('{','}')],[('[',']'),('[',']')]]. Then it callsgwith the transformed list.- The remaining functions use a partially continuation-passing style intermingled with list manipulation. Each continuation function
ctakes a listlof remaining bracket tuple lists and returns a list of possible strings to be suffixed to what's already been generated. g lgenerates the list of fully matched strings formable by using all the brackets inl.- It does this by calling
l#gto generate strings beginning with some bracket. The recursivegparameter is itself used as a continuation by#, to generate what comes after the first bracketed subelement. - In the case where there are no such strings (because
lhas no brackets left inside)ginstead returns[""], the list containing just the empty string. Since[""]compares smaller to all nonempty lists produceable by#, we can do this by applyingmax.
- It does this by calling
l#cgenerates strings fromlbeginning with at least one bracketed subelement, leaving to the continuationcto determine what follows the element.bandeare a selected pair of brackets in the tuplex, andris the list of remaining tuples of the same bracket type.r:filter(/=x:r)lislwith the tuplexremoved, slightly rearranged.?is called to generate the possible subelements betweenbande. It gets its own continuationmap(e:).c, which prefixeseto each of the suffix strings generated byc.#itself prepends the initialbto all the strings generated by?andc.
l?cgenerates the fully matched strings formable by using zero or more bracket pairs froml, and then leaves to its continuationcto handle what's left over. Thec lpart goes directly tocwithout adding any subelements, whilel#(?c)uses#to generate one subelement and then call(?c)recursively for possible further ones.
Jelly, (削除) 50 40 (削除ここまで) 34 bytes
-6 bytes thanks to Leaky Nun (getting reduce to work where I couldn't)
"()"{}"[]"<>"©ẋ"FŒ!QμW;®œṣF\/μÐLÐḟ
Plain and inefficient.
Try it online! (times out at TIO for [1,1,1,1] - yes, inefficient.)
How?
Recursively removes pairs of matching brackets that reside right next to each other until no more may be removed for every possible string one may form, keeping such strings which reduce to nothing (hence have all matching content).
"()"{}"[]"<>"©ẋ"FŒ!QμW;®œṣF\/μÐLÐḟ - Main link: list: [n(), n{}, n[], n<>]
"()"{}"[]"<>" - literal ["()", "{}", "[]", "<>"]
© - copy to register
" - zip with:
ẋ - repeat list
F - flatten
Œ! - all permutations (yeah, it's inefficient!)
Q - de-duplicate
μ - monadic chain separation
Ðḟ - filter discard if (non empty is truthy):
μÐL - loop until no change:
® - recall value from register
W - wrap loop variable in a list
; - concatenate
\/ - reduce with last two links as a dyad:
œṣ - split left on occurrences of sublist on the right
F - flatten the result
-
1
-
1
-
\$\begingroup\$ @LeakyNun Thanks! I tried but couldn't get a reduce to work (hence resorted to using eval). \$\endgroup\$Jonathan Allan– Jonathan Allan2017年04月28日 04:41:15 +00:00Commented Apr 28, 2017 at 4:41
-
\$\begingroup\$ Nice, I used the same approach of
œṣ-F-µÐLin a somewhat related problem. \$\endgroup\$Adalynn– Adalynn2017年09月09日 21:43:32 +00:00Commented Sep 9, 2017 at 21:43
05AB1E, (削除) 33 (削除ここまで) (削除) 32 (削除ここまで) (削除) 30 (削除ここまで) (削除) 27 (削除ここまで) 25 bytes
Saved 7 bytes thanks to Riley.
Input order is [(),<>,[],{}]
×ばつ©JœJÙD[D®õ:DŠQ#]€g_Ï
Explanation
žu # push the string "()<>[]{}"
4ä # split in 4 parts
© # store a copy in register
×ばつ # repeat each bracket a number of times decided by input
JœJÙ # get the unique permutations of the string of brackets
D # duplicate
[ # start infinite loop
D # duplicate current list of permutations
®õ: # replace any instance of (), [], <>, {}
# with an empty string
DŠ # duplicate and move down 2 places on stack
Q# # if the operation didn't alter the list, exit loop
] # end loop
€g # get the length of each subtring
_Ï # keep only the strings in the original
# list of unique permutations
# that have a length of 0 in the resulting list
-
\$\begingroup\$ 1. I think
:vectorizes (you can skip most of the infinite loop). 2. It's 1 bytes shorter to useUXat the beginning andXwhen you need the list of brackets again. \$\endgroup\$Riley– Riley2017年04月28日 14:21:30 +00:00Commented Apr 28, 2017 at 14:21 -
\$\begingroup\$ @Riley: I did try just
:first, but we get issues when for example replacements on{}creates possible replacements on()as we've already tried replacing all(). Good point aboutUXthough. We can get another byte with©®as well. \$\endgroup\$Emigna– Emigna2017年04月28日 14:30:13 +00:00Commented Apr 28, 2017 at 14:30 -
\$\begingroup\$ The fact that
Upops the top was always frustrating. I didn't know about©®. \$\endgroup\$Riley– Riley2017年04月28日 14:39:25 +00:00Commented Apr 28, 2017 at 14:39 -
\$\begingroup\$ I was looking at this answer. Did 05AB1E get an update that broke it, or is that answer not valid? \$\endgroup\$Riley– Riley2017年04月28日 14:40:25 +00:00Commented Apr 28, 2017 at 14:40
-
\$\begingroup\$ That answer works for
[([]{})<{[()<()>]}()>{}], but not for[({})<{[()<()>]}()>{}]. The only difference is the removed[]. I'll ask about it in TNB. \$\endgroup\$Riley– Riley2017年04月28日 14:46:15 +00:00Commented Apr 28, 2017 at 14:46
Pyth - (削除) 83 (削除ここまで) (削除) 74 (削除ここまで) (削除) 71 (削除ここまで) 63 bytes
K("\[]""{}""\(\)""<>")Fd{.psm*:@Kd*\2円k@QdU4JdVldFHK=:JHk))I!Jd
1: Kc"[] {} () <>")Fd{.ps*V-R\KQJdVldFHK=:JHk))I!Jd
Also, this 53-byte version thanks to Leaky Nun
Kc"\[] \{} \(\) <>")Fd{.ps*V-R\\KQJdVldFHK=:JHk))I!Jd
-
\$\begingroup\$ Jelly beaten by Pyth? What is this sorcery? \$\endgroup\$math junkie– math junkie2017年04月27日 23:45:18 +00:00Commented Apr 27, 2017 at 23:45
-
\$\begingroup\$ @mathjunkie I didn't beat Jelly; I screwed up the input syntax. \$\endgroup\$Maria– Maria2017年04月28日 00:08:38 +00:00Commented Apr 28, 2017 at 0:08
-
\$\begingroup\$ ...and I think I can improve :D \$\endgroup\$Jonathan Allan– Jonathan Allan2017年04月28日 00:20:05 +00:00Commented Apr 28, 2017 at 0:20
-
\$\begingroup\$ @JonathanAllan so can this answer. \$\endgroup\$Leaky Nun– Leaky Nun2017年04月28日 03:39:00 +00:00Commented Apr 28, 2017 at 3:39
-
1\$\begingroup\$ Step 1: instead of
("\[]""{}""\(\)""<>"), we doc"\[] \{} \(\) <>")(split on whitespace); instead of:@Kd*\2円k, we do-@Kdfollowed by two backslashes; then, instead of mapping onU4, we do*V-R\\KQ(multiply two arrays in parallel). The first array is generated usingR, namely-R\\kThis will give you a 54-byte version \$\endgroup\$Leaky Nun– Leaky Nun2017年04月28日 03:43:24 +00:00Commented Apr 28, 2017 at 3:43
Ruby, 123 bytes
->a{"<>{}[]()".gsub(/../){$&*a.pop}.chars.permutation.map(&:join).uniq.grep /^((\(\g<1>\)|\[\g<1>\]|\{\g<1>\}|<\g<1>>)*)$/}
Try it online! It's inefficient, though, so even inputs like [1,2,1,1] will time out online. All the listed examples will work, at least!
Explanation
->a{ # Procedure with input a
"<>{}[]()".gsub(/../){ # For all pairs of brackets
$&*a.pop # Pop last item in input, then repeat
# the bracket pair by that number
}.chars # Get characters
.permutation # All permutations of characters
.map(&:join) # For each permutation, join the chars
.uniq # Get unique permutations only
.grep /^((\(\g<1>\)|\[\g<1>\]|\{\g<1>\}|<\g<1>>)*)$/}
# Only return permutations that match
# this bracket-matching regex
Explore related questions
See similar questions with these tags.