# Equal out bracket types

Based on THIS question.

Given a string, replace each bracket ()[]{}<> with a bracket of the appropriate type so that the brackets match, and the nested brackets cycle as follows:

1. Outermost ones are ()
2. Directly inside of () should be []
3. Directly inside of [] should be {}
4. Directly inside of {} should be <>
5. Directly inside of <> will be () again (cycles)

All non-bracket chars must remain exactly as they are. Open brackets may only be replaced with open brackets of some type, and close brackets with close brackets.

The input will always make this possible. This means its brackets matched correctly if their type is ignored. So, {ab<)c] is a valid input, but ab)(cd or ab((cd are not.

Examples:

2#jd {¤>. = 2#jd (¤).
abcdef    = abcdef
(3×5+(4-1)) = (3×5+[4-1])
<<<>><<>><<<<<<>>>>>>> = ([{}][{}][{<([{}])>}])


The use of native transforming of input this way (auto syntax of language) is not allowed.

As always: shortest code wins.

• I don't understand the challenge. What must the output be in terms of the input? – xnor Dec 11 '16 at 5:39
• @xnor the output should be the same string like the input, except for the four kinds of brackets. They need to be replaced to match the pattern. – Dirk Reichel Dec 11 '16 at 5:49
• Ah, now I see. I didn't understand that the "should be" are things you're supposed to make be true. I'll edit to try to make it clearer. – xnor Dec 11 '16 at 5:50
• @DirkReichel I don't think that is something you need to worry about. I can't imagine that any language can do this specific transformation natively, and in the unlikely event that there is such a language all that means is that answers in that language won't be very interesting. – Martin Ender Dec 11 '16 at 10:08
• @DirkReichel what's the point? Just stick with ASCII. Using different characters adds nothing to the challenge apart from unnecessary restrictions on ascii-only languages. – FlipTack Dec 11 '16 at 13:19

## JavaScript (ES6), 79 bytes

s=>s.replace(/./g,c=>~(p=l.indexOf(c))?l[p&4?--k&3|4:k++&3]:c,l='([{<)]}>',k=0)


### Test cases

let f =

s=>s.replace(/./g,c=>~(p=l.indexOf(c))?l[p&4?--k&3|4:k++&3]:c,l='([{<)]}>',k=0)

console.log(f("2#jd {¤>."));
console.log(f("abcdef"));
console.log(f("(3×5+(4-1))"));
console.log(f("<<<>><<>><<<<<<>>>>>>>"));

# Lex, 132 bytes

%{
int i,o[4]={40,91,123,60};
%}
%%
[[({<] {putchar(o[i++&3]);}
[])}>] {putchar(o[--i&3]+2-!(i&3));}
%%
yywrap(){}
main(){yylex();}

• You can save 27 bytes (portable lex) or 30 bytes (using flex as the compiler) via deleting the last two or three lines respectively, at a cost of some number of bytes (probably 2, 3 or 4; the rules are somewhat unclear) in penalties for the -ll command line option when linking the resulting C file. (That is, instead of compiling with lex brackets.l; cc lex.yy.c, you compile with lex brackets.l; cc lex.yy.c -ll.) That's definitely a tradeoff worth making in this situation. – user62131 Dec 13 '16 at 14:16

# Java, 155 bytes

a->{String s="([{<)]}>";for(int i=0,j=0,k;i<a.length;i++){k=s.indexOf(a[i]);if(k>3){a[i]=s.charAt(--j%4+4);}else if(k>-1){a[i]=s.charAt(j++%4);}}return a;}


Lambda that takes a char[] as it's single argument. We loop through the array, storing it's position in our string of brackets (s) in a variable (k). We check if it's an opening or closing bracket (s.indexAt()), and replace it with the appropriate bracket based on it's level of nesting (s.charAt()), looping appropriately with %4

# Haskell, 126 bytes

b="([{<"
d=")]}>"
y=cycle
(!)=elem
f(e:c)n(x:r)|x!b=y b!!n:f(y d!!n:e:c)(n+1)r|x!d=e:f c(n-1)r|1<3=x:f(e:c)n r
f c n s=s
f" "0


Try it on ideone. Usage:

*Main> f" "0 "<<<>><<>><<<<<<>>>>>>>"
"([{}][{}][{<([{}])>}])"


### Explanation

f takes three arguments: A string that works as stack for closing brackets, an int n for counting the nesting-depth and the input string.

f c n "" = ""                            -- base case for recursion: input string is empty
f (e:c) n (x:r)                          -- for the current char x
| elem x "([{<" =                     -- check if it is an opening bracket
(cycle "([{<")!!n :               --   if so, replace it with a bracket of the current nesting depth
f ((cycle ")]}>")!!n : e : c) --   push the matching closing bracket on the stack
(n+1) r                   --   increase depth level and check the next char
| elem x ")]}>" =                     -- if x is a closing bracket
e :                               --   replace it by the closing bracket from on top of the stack
f c (n-1) r                   --   decrement depth level and check the next char
| otherwise     = x : f (e:c) n r     -- otherwise keep x and check the next char