# Horizontally mirror a brainflak program

Your task is to write a program or function which takes a pure brainflak program as input (assume it contains only balanced ()[]{}<>), and output a visually mirrored copy of it.

If you reversed a brainflak program as a string, say ({}()) (add one to an input), you would get ))(}{(, which is not valid.

Instead, you should mirror it, by reversing the direction of the parentheses/brackets/braces/angle-brackets, like what you would see if the program was placed in front of a mirror: ((){}).

Test cases (??? means anything is okay):

()               -> ()
({}[{}])         -> ([{}]{})
()[]             -> []()
<(){}[]>         -> <[]{}()>
([{<()[]{}<>>}]) ->([{<<>{}[]()>}])
(a)              -> ???
{>               -> ???
))(}{(           -> ???
()↵[]            -> ???


This is a code golf challenge, shortest answer per language wins.

• I'd recommend removing the invalid test cases as they add nothing to the challenge, and instead add some edge cases, or something maybe a little longer Nov 9 '19 at 15:48
• @cairdcoinheringaahing What edge cases would you recommend? Nov 9 '19 at 15:48
• Maybe something like ([{<()[]{}<>>}]) or similarly convoluted? Nov 9 '19 at 15:51
• I think I know exactly what prompted this challenge heh :P Nov 9 '19 at 17:08
• A nice brain-flak term to describe the inputs: a pure brain-flak program contains only (){}[]<> and is perfectly balanced. Nov 9 '19 at 17:26

# Charcoal, 3 bytes

Ｓ‖Ｔ


Try it online! Link is to verbose version of code. Explanation: Ｓ reads the input and implicitly echos it, while ‖ is the mirroring operator, which normally just reverses the input, but the Ｔ modifies it to mirror the characters at the same time.

• +1 right primitive for the job Nov 9 '19 at 17:21

# Python 3, 47 bytes

lambda x:x[::-1].translate('>]<[)('*20+'}_{'*2)


Try it online!

Python has a convenient string method translate that accepts a translation string s, and maps each character c to s[ord(c)]. So, we just need to make a translation string with the right characters at the positions of ASCII values [40, 41, 60, 62, 91, 93, 123, 125] of ()<>[]{}.

The ideal would be to make the table like '????????'*16, putting the correct character for each ASCII value modulo 8. Unfortunately, the values [40, 41, 60, 62, 91, 93, 123, 125] are not distinct modulo 8, and the first modulus making them distinct is 18, which would mean something like '??????????????????'*6.

However, conveniently, the lowest 6 ASCII values [40, 41, 60, 62, 91, 93] are distinct modulo 6. That lets us handle them with '>]<[)('*20, translating ASCII values 0 through 119. For the remaining two, 123 and 125, we use '}_{'*2 to hit the next 6 ASCII values 120 to 125. Python 3 lets us stop there, unlike Python 2, which requires the translation string to be length 256 exactly.

# JavaScript (Node.js),  51 47  44 bytes

Saved 3 bytes thanks to @xnor

s=>Buffer(s).map(c=>c^68%c/3%8).reverse()+''


Try it online!

### How?

For each pair of characters, we can switch from the 1st to the 2nd character (and vice versa) by XOR'ing the ASCII code with $$\1\$$, $$\2\$$ or $$\6\$$.

 char 1 | code | XOR | code | char 2
--------+------+-----+------+--------
'('  |   40 |  1  |   41 |  ')'
'<'  |   60 |  2  |   62 |  '>'
'['  |   91 |  6  |   93 |  ']'
'{'  |  123 |  6  |  125 |  '}'


Given an ASCII code $$\c\$$, we can turn it into the correct XOR value by using the following function:

$$f(c)=\left\lfloor((68 \bmod c)/3)\bmod 8\right\rfloor$$

   c  | 68 mod c |   / 3  | mod 8 | floor
------+----------+--------+-------+-------
40 |    28    |  9.333 | 1.333 |   1
41 |    27    |    9   |   1   |   1
------+----------+--------+-------+-------
60 |     8    |  2.667 | 2.667 |   2
62 |     6    |    2   |   2   |   2
------+----------+--------+-------+-------
91 |    68    | 22.667 | 6.667 |   6
93 |    68    | 22.667 | 6.667 |   6
123 |    68    | 22.667 | 6.667 |   6
125 |    68    | 22.667 | 6.667 |   6

• Why Buffer(s) instead of s.split? Nov 9 '19 at 16:26
• @RedwolfPrograms [...s] would be shorter than using split. But this answer is working on ASCII codes, not on characters. Nov 9 '19 at 16:31
• Oh, I get it now. (I've also never though of using the ... operator on strings, that's handy to know) Nov 9 '19 at 16:32
• I brute forced some expressions for the XOR value table and got 68%c/3%8, which seems to work for 3 bytes shorter: TIO
– xnor
Nov 9 '19 at 21:21

# Jelly,  13  12 bytes

Saved 1 byte thanks to @JonathanAllan

O&80%15‘^OỌṚ


Try it online!

### How?

The idea here is to XOR the ASCII codes to turn each character into its mirrored counterpart, like I did in my JS answer. But we use a formula that is bit golfier in Jelly:

$$f(c)=((c\text{ & }80)\bmod 15)+1$$

where $$\\text{&}\$$ is a bitwise AND.

 char | code | and 80 | mod 15 |  + 1 | XOR code | new char
------+------+--------+--------+------+----------+----------
'(' |   40 |    0   |    0   |   1  |    41    |   ')'
')' |   41 |    0   |    0   |   1  |    40    |   '('
------+------+--------+--------+------+----------+----------
'<' |   60 |   16   |    1   |   2  |    62    |   '>'
'>' |   62 |   16   |    1   |   2  |    60    |   '<'
------+------+--------+--------+------+----------+----------
'[' |   91 |   80   |    5   |   6  |    93    |   ']'
']' |   93 |   80   |    5   |   6  |    91    |   '['
'{' |  123 |   80   |    5   |   6  |   125    |   '}'
'}' |  125 |   80   |    5   |   6  |   123    |   '{'


### Commented

O&80%15‘^OỌṚ - a monadic link taking a string, e.g. "(<>[])"
O            - convert the input to ASCII codes --> [40, 60, 62, 91, 93, 41]
&80         - bitwise AND with 80              --> [ 0, 16, 16, 80, 80,  0]
%15      - modulo 15                        --> [ 0,  1,  1,  5,  5,  0]
‘     - increment                        --> [ 1,  2,  2,  6,  6,  1]
O   - input to ASCII codes again       --> [40, 60, 62, 91, 93, 41]
^    - bitwise XOR                      --> [41, 62, 60, 93, 91, 40]
Ọ  - convert back to characters       --> ")><][("
Ṛ - reverse                          --> "([]<>)"

• I've used up all of my votes for today, imaginary +1 Nov 9 '19 at 21:56
• You can save one if you avoid the register use by taking advantage of chaining rules and repeating O like so: O&80%15‘^OỌU (side note: personally I go for Ṛ when U's depth action is not required, so would do O&80%15‘^OỌṚ) Nov 9 '19 at 23:45

# 05AB1E, 4 bytes

º2äθ


Explanation

º    | Mirror (i.e. "({}[{}])" -> "({}[{}])([{}]{})"
2ä  | Split into two pieces
θ | Take the last piece


# Canvas, 1 byte

↔


Try it here!

Surprised that this is the first 1-byte answer.

# J, 24 bytes

|.rplc(;"0|.)@'([{<>}])'


Try it online!

Test cases by Jonah.

# Retina 0.8.2, 20 bytes

O^$. T([{<>}])Ro  Try it online! Link includes test cases. Explanation: O.  Sort individual characters... $


... by substitution value (constant empty string, therefore keeps original order)...

^


... with reversed sort order (i.e. reversing the string).

T([{<>}])


Substitute each character of ([{<>}])...

Ro


... with the matching character from the reverse of that string, thus mirroring those characters.

• Note that in Retina 1 you can save 4 bytes by using V to reverse the string instead of O..
– Neil
Nov 9 '19 at 17:31

# J, 32 25 bytes

'([{<)]}>'|.@([{~8|4+i.)]


Try it online!

Quick explanation:

• Find the index of each input char within the string '([{<)]}>'.
• Add 4 to it to get its mirror
• Take that mod 8 to handle wrapping around to the beginning
• Use the result to index back into '([{<)]}>'
• And reverse that result
• 24 bytes using rplc Nov 9 '19 at 18:50
• @GalenIvanov, v nice! i think it's different enough in both concept and implementation that you should feel free to post separately. Nov 9 '19 at 19:01
• Ok, thanks! I'll post it separately. Nov 9 '19 at 19:07

# Japt, 12 bytes

Blatant port of Arnauld's JS solution so go upvote him.

ÔcÈ^68%X/3%8


Try it

# Python 3, 61 bytes

lambda x,s="([<{}>])":"".join(s[7-s.find(c)]for c in x[::-1])


Try it online!

# Icon, 67 bytes

procedure f(s)
r:="reverse"
return map(r(s),d:="([{<>}])",r(d))
end


Try it online!

• Cool idea for finding the mirroring. Is Icon a language worth looking into? Nov 9 '19 at 18:50
• @Jonah Thank you! Yes, I think so, but keep in mind it's an old language. Icon is one of the first languages to have generators. A cool concept is the "goal directed evaluation" - if some expression fails, Icon automatically backtracks and generates another value(s) if there's a generator involved. Nov 9 '19 at 18:59

# Jelly, 13 bytes

This approach has many 13-byte solutions, although I can golf Arnauld's 13 byter to 12 bytes.

QṢiⱮịQṢṭ2/FƲṚ


Try it online!

### How?

QṢiⱮịQṢṭ2/FƲṚ - Link: list of characters, P
Q             - de-duplicate (P)
Ṣ            - sort (call this X)
Ɱ          - map across (p in) P with:
i           -   first index of (p) in (X)
Q        -   de-duplicate (P)
Ṣ       -   sort
2/    -   2-wise reduce with:
ṭ      -     tack
F   -   flatten (i.e. pair-wise reversal of sorted unique values)
ị         - (left) index into (right)
Ṛ - reverse


# Brain-Flak, 302 bytes

{(({}(<()>))<({}[(((()()()()()){}){}){}])>{[()](<()>)}{}<({}[()])>{()(<()>)}{}<({}[(((()()())){}{}){}()])>{[()()](<()>)}{}<({}[()()])>{()()(<()>)}{}<({}[(((()()()){}()){}){}()])>{[()()](<()>)}{}<({}[()()])>{()()(<()>)}{}<({}[(((()()()()()){})){}{}])>{[()()](<()>)}{}<({}[()()])>{()()(<()>)}{}<>)<>{}}<>


Try it online!

This is (currently) very poorly golfed, but I thought there ought to be at least one Brain-Flak answer to this question.

# Red, 56 bytes

func[s][foreach c reverse s[prin select"[][()({}{<><"c]]


Try it online!

# Jelly, 15 bytes

“[({})]”©iⱮUịUɼ


Try it online!

A monadic link that reverses the input and input brackets of all their types.

# Perl 5-p, 32 bytes

\$_=reverse y/(){}[]<>/)(}{][></r


Try it online!

# C (gcc), 858464 60 bytes

60 bytes thanks to Neil

p;f(char*s){for(p=strlen(s);p--;)putchar(s[p]^68%s[p]/3%8);}


Try it online!

• 60 bytes
– Neil
Nov 12 '19 at 11:49