Equal out bracket types

9

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.

Dirk Reichel

Posted 2016-12-11T01:24:59.347

Reputation: 337

I don't understand the challenge. What must the output be in terms of the input? – xnor – 2016-12-11T05:39:44.520

@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 – 2016-12-11T05:49:02.810

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 – 2016-12-11T05:50:38.397

I edited the specs. Feel free to change things if I messed them up. I'm not sure what "native transforming of input" means, so I left it alone. – xnor – 2016-12-11T05:59:45.957

@xnor I wasn't sure how to put it, but there may be languages which will transform brackets just by the compiler in some way. And I don't want a use of something like that... – Dirk Reichel – 2016-12-11T06:18:43.660

1@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 – 2016-12-11T10:08:08.087

What characters can appear in the input? I see you've got some non-ASCII there. – Martin Ender – 2016-12-11T10:09:13.240

@MartinEnder in theory: all printable unicode symbols. – Dirk Reichel – 2016-12-11T12:39:13.193

2@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 – 2016-12-11T13:19:22.090

@Flp.Tkc there is no "need to run with unicode". If your language is ascii-only, only ascii inputs need to run. I assumed something like that as completely "off topic" for this task. – Dirk Reichel – 2016-12-11T18:04:01.627

Answers

2

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("<<<>><<>><<<<<<>>>>>>>"));

Arnauld

Posted 2016-12-11T01:24:59.347

Reputation: 111 334

1

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

Laikoni

Posted 2016-12-11T01:24:59.347

Reputation: 23 676

1

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();}

Rainer P.

Posted 2016-12-11T01:24:59.347

Reputation: 2 457

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. – None – 2016-12-13T14:16:47.743

1

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

Xanderhall

Posted 2016-12-11T01:24:59.347

Reputation: 1 236