15
\$\begingroup\$

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.

\$\endgroup\$
13
  • 1
    \$\begingroup\$ 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 \$\endgroup\$ Nov 9, 2019 at 15:48
  • \$\begingroup\$ @cairdcoinheringaahing What edge cases would you recommend? \$\endgroup\$ Nov 9, 2019 at 15:48
  • \$\begingroup\$ Maybe something like ([{<()[]{}<>>}]) or similarly convoluted? \$\endgroup\$ Nov 9, 2019 at 15:51
  • 6
    \$\begingroup\$ I think I know exactly what prompted this challenge heh :P \$\endgroup\$
    – hyper-neutrino
    Nov 9, 2019 at 17:08
  • 6
    \$\begingroup\$ A nice brain-flak term to describe the inputs: a pure brain-flak program contains only (){}[]<> and is perfectly balanced. \$\endgroup\$
    – DJMcMayhem
    Nov 9, 2019 at 17:26

18 Answers 18

10
\$\begingroup\$

Charcoal, 3 bytes

S‖T

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.

\$\endgroup\$
1
  • 3
    \$\begingroup\$ +1 right primitive for the job \$\endgroup\$
    – Jonah
    Nov 9, 2019 at 17:21
7
\$\begingroup\$

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.

\$\endgroup\$
7
\$\begingroup\$

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
\$\endgroup\$
4
  • \$\begingroup\$ Why Buffer(s) instead of s.split``? \$\endgroup\$ Nov 9, 2019 at 16:26
  • \$\begingroup\$ @RedwolfPrograms [...s] would be shorter than using split. But this answer is working on ASCII codes, not on characters. \$\endgroup\$
    – Arnauld
    Nov 9, 2019 at 16:31
  • \$\begingroup\$ Oh, I get it now. (I've also never though of using the ... operator on strings, that's handy to know) \$\endgroup\$ Nov 9, 2019 at 16:32
  • 2
    \$\begingroup\$ 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 \$\endgroup\$
    – xnor
    Nov 9, 2019 at 21:21
6
\$\begingroup\$

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                          --> "([]<>)"
\$\endgroup\$
2
  • \$\begingroup\$ I've used up all of my votes for today, imaginary +1 \$\endgroup\$ Nov 9, 2019 at 21:56
  • 1
    \$\begingroup\$ 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ỌṚ) \$\endgroup\$ Nov 9, 2019 at 23:45
5
\$\begingroup\$

05AB1E, 4 bytes

º2äθ

Try it online! or verify all test cases

Explanation

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

Canvas, 1 byte

Try it here!

Surprised that this is the first 1-byte answer.

\$\endgroup\$
4
\$\begingroup\$

J, 24 bytes

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

Try it online!

Test cases by Jonah.

\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Note that in Retina 1 you can save 4 bytes by using V` to reverse the string instead of O`.. \$\endgroup\$
    – Neil
    Nov 9, 2019 at 17:31
2
\$\begingroup\$

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
\$\endgroup\$
3
  • \$\begingroup\$ 24 bytes using rplc \$\endgroup\$ Nov 9, 2019 at 18:50
  • \$\begingroup\$ @GalenIvanov, v nice! i think it's different enough in both concept and implementation that you should feel free to post separately. \$\endgroup\$
    – Jonah
    Nov 9, 2019 at 19:01
  • \$\begingroup\$ Ok, thanks! I'll post it separately. \$\endgroup\$ Nov 9, 2019 at 19:07
2
\$\begingroup\$

Japt, 12 bytes

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

ÔcÈ^68%X/3%8

Try it

\$\endgroup\$
1
\$\begingroup\$

Python 3, 61 bytes

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

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Icon, 67 bytes

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

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Cool idea for finding the mirroring. Is Icon a language worth looking into? \$\endgroup\$
    – Jonah
    Nov 9, 2019 at 18:50
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ Nov 9, 2019 at 18:59
1
\$\begingroup\$

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)
           Ʋ  - last four links as a monad - i.e. f(P):
     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
\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

Red, 56 bytes

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Jelly, 15 bytes

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

Try it online!

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

\$\endgroup\$
0
\$\begingroup\$

Perl 5 -p, 32 bytes

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

C (gcc), 85 84 64 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!

\$\endgroup\$
1
  • \$\begingroup\$ 60 bytes \$\endgroup\$
    – Neil
    Nov 12, 2019 at 11:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.