21
\$\begingroup\$

Task:

Input will consist of some text, with nested [] separating some of it into nested groups:

abc[d[fgijk]nopq]rst[u[v[[w]]]xy[[[z]]]]

Your task is to remove all brackets, and everything wrapped in an odd number of brackets. For example, a[b]c would remove the [], and the b inside of it. a[[b]]c, however, would only remove the brackets (as b is wrapped in an even number of brackets). If the string were instead a[b[c]d]f, the result would be acf, as the b and d are wrapped in an odd number of brackets, but c is not.

The correct output for the input given at the top would be:

abcfgijkrstvwz

I/O:

You can take input as a string, or any reasonable representation of one (like an array of characters). You can output in a similar fashion, with trailing whitespacing being allowed. You can assume all non-bracket characters are lowercase letters, and you can choose whether the brackets are (), [], or {}.

You can assume the brackets are properly nested (e.g., [ or ][ won't be given as inputs), and that there is at least one letter in the input.

Test cases:

abc                                                 abc
a[b]c                                               ac
[ab]c                                               c
ab[c]                                               ab
[]abc                                               abc
a[]bc                                               abc
abc[]                                               abc
a[[b]]c                                             abc
a[[[b]]]c                                           ac
a[b][c]d                                            ad
a[b][]c                                             ac
[a[b]c]                                             b
a[b[c]d]f                                           acf
[ab]c[df]                                           c
a[a]a[[a]]                                          aaa
abc[d[fgijk]nopq]rst[u[v[[w]]]xy[[[z]]]]            abcfgijkrstvwz
zyx[w]v[ut[s]r[[qp][kj]i]gf][d][][][c][b[][a]]      zyxvsia

Other:

This is , so shortest answer (in bytes) per language wins!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Can we require input to be uppercase instead of lowercase? \$\endgroup\$
    – pxeger
    Sep 1, 2021 at 8:20
  • 1
    \$\begingroup\$ @pxeger No, sorry. \$\endgroup\$ Sep 1, 2021 at 15:01

31 Answers 31

10
\$\begingroup\$

Retina, 7 bytes

\W\w*.

Try it online!

  • -7 bytes (50%) thanks to DLosc :)
\$\endgroup\$
3
  • \$\begingroup\$ 7 bytes (but doesn't work with multiple test cases at once) \$\endgroup\$
    – DLosc
    Sep 1, 2021 at 3:34
  • \$\begingroup\$ @DLosc Ah, I missed the note that I can assume the input only contains [, ] and letters. \$\endgroup\$
    – tsh
    Sep 1, 2021 at 3:38
  • \$\begingroup\$ [][].*?[][] would have worked for the first approach. To use @DLosc's approach with multiple test cases simply put %(G` in the header. \$\endgroup\$
    – Neil
    Sep 1, 2021 at 9:23
10
\$\begingroup\$

Jelly, 10 8 bytes

e€Ø[œpm2

Try it online! or see all test cases

Full program as we use Jelly' smash printing. Uses some tricks from Jonah's J answer, so be sure to upvote that as well!

-2 bytes thanks to Nick Kennedy.

How it works

e€Ø[œpm2 - Main link. Takes a string S on the left e.g. S = "a[b[c]d]e"
  Ø[     - Builtin constant; Yield "[]"
 €       - Over each character in S:
e        -   Is it a bracket?                      e.g. [0,1,0,1,0,1,0,1,0] 
    œp   - Partition S at the truthy indices       e.g. [['a'], ['b'], ['c'], ['d'], ['e']]
      m2 - Take every second sublist               e.g. [['a'], ['c'], ['e']]
           Smash-print and return                  e.g. 'abc'
\$\endgroup\$
2
  • 2
    \$\begingroup\$ Here’s a two byte saving: e€Ø[œpm2 \$\endgroup\$ Sep 1, 2021 at 7:44
  • \$\begingroup\$ @NickKennedy Very nice! \$\endgroup\$ Sep 1, 2021 at 8:04
10
\$\begingroup\$

Vyxal s, 4 bytes

øW4Ḟ

Try it Online!

øW   # Split on words (Matches sequences of word chars + single non-word chars)
     # (Used for dictionary compression algorithm)
  4Ḟ # Get every fourth item.

Beating Jelly :) -2 thanks to Aaron Miller.

\$\endgroup\$
4
  • \$\begingroup\$ What a gamer winning the challenge. Very cool \$\endgroup\$
    – lyxal
    Sep 1, 2021 at 3:34
  • \$\begingroup\$ @exedraj Because of abusing various builtins, I can actually get 6 for uppercase :) \$\endgroup\$
    – emanresu A
    Sep 1, 2021 at 3:35
  • \$\begingroup\$ @exedraj Also, DLosc came up with 7 in Retina. \$\endgroup\$
    – emanresu A
    Sep 1, 2021 at 3:36
  • 3
    \$\begingroup\$ Not any more, @exedraj! :p \$\endgroup\$
    – Shaggy
    Sep 1, 2021 at 8:46
9
\$\begingroup\$

Japt v2.0a0 -P, 7 5 bytes

Vyxal was being too cocky for my liking! :D

q\W ë

Try it or run all test cases

q\W ë     :Implicit input of string
q         :Split on
 \W       :  RegEx /[^a-z0-9]/i
    ë     :Get every second element, starting with the first
          :Implicitly join and output
\$\endgroup\$
2
  • \$\begingroup\$ Nooo why would you do this?!? :p \$\endgroup\$
    – lyxal
    Sep 1, 2021 at 9:19
  • 2
    \$\begingroup\$ Not any more, Shaggy. \$\endgroup\$
    – emanresu A
    Mar 15, 2022 at 10:06
9
\$\begingroup\$

J, 39 24 23 18 15 bytes

#~'_'(*=/\)@I.]

Try it online!

-3 bytes and new approach thanks to FrownyFrog!

old answer, 39 24 23 18 bytes

(+:~:/\)@e.&'[]'#]

Try it online!

Saved around 10 bytes after reading dingledooper's answer and realizing I didn't have distinguish between open and close brackets.

-6 thanks to some damn clever tricks by Bubbler!

Consider 'a[b[c]d]f':

  • e.&'[]' Is the input a bracket? Returns a boolean mask:

    0 1 0 1 0 1 0 1 0
    
  • (+:~:/\)@ Transform that mask first by a scan using a not equal reduction. Only items with odd numbers of brackets to their left (including themselves) become 1. Then "not-or" +: that result with the original mask:

    1 0 0 0 1 0 0 0 1
    
  • #] Use that to filter the original input:

    acf
    
\$\endgroup\$
5
  • 1
    \$\begingroup\$ 2|+/\~:/\ \$\endgroup\$
    – Bubbler
    Sep 1, 2021 at 2:06
  • 1
    \$\begingroup\$ 18 \$\endgroup\$
    – Bubbler
    Sep 1, 2021 at 2:31
  • 1
    \$\begingroup\$ Oh that's really clever. I don't think I've ever used dyadic +: in a golf before.... \$\endgroup\$
    – Jonah
    Sep 1, 2021 at 2:36
  • \$\begingroup\$ Oh my, I was really not expecting any more golfs after that 18. Well done! \$\endgroup\$
    – Jonah
    Sep 9, 2021 at 15:30
  • \$\begingroup\$ It's not really a new approach, I just flipped everything. Not a bracket, equality, "and" instead of "not-or". \$\endgroup\$
    – FrownyFrog
    Sep 10, 2021 at 3:29
6
\$\begingroup\$

Python 3, 45 bytes

Input is taken from STDIN, and outputs a list of characters, each on its own line.

n=1
for c in input():n^=c<'a'or n>0==print(c)

Try it online!

The main observation is that whether or not a letter is wrapped in an odd number of brackets can be solely determined by taking the parity of the number of brackets preceding that letter.

Python 3, 48 bytes

Same as above, but outputs the entire string on one line.

n=1
for c in input():n^=not'`'<c!=print(end=c*n)

Try it online!

Python 3.8 (pre-release), 49 bytes

A lambda-based solution which is just slightly longer, in comparison:

lambda L,n=1:[c for c in L if(n:=n^(b:=c<'a'))>b]

Try it online!

\$\endgroup\$
6
\$\begingroup\$

Wolfram Language (Mathematica), 40 bytes

StringSplit[#,"["|"]",All][[;;;;2]]<>""&

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ What do all the semicolons do? \$\endgroup\$
    – Jonah
    Sep 1, 2021 at 5:33
  • 1
    \$\begingroup\$ @Jonah It's similar to Python's slice, but with ;; instead of : (Span). \$\endgroup\$
    – att
    Sep 1, 2021 at 6:41
6
\$\begingroup\$

R, 33 32 bytes

-1 byte thanks to @Shaggy.

function(s)gsub("\\W\\w*.","",s)

Try it online!

Simple regex-based solution.

\$\endgroup\$
2
  • \$\begingroup\$ Save a byte by changing the RegEx to "\\W\\w*.". \$\endgroup\$
    – Shaggy
    Sep 1, 2021 at 9:16
  • \$\begingroup\$ @Shaggy, thanks! I somehow missed that. \$\endgroup\$
    – pajonk
    Sep 1, 2021 at 9:20
6
\$\begingroup\$

Zsh, 19 bytes

<<<${(e)1//[][]/\`}

Attempt This Online!

Replaces [ and ] with `, and (e)xpands the backtick substitutions. For example, A[[]BCD] becomes

A```BCD`

The contents of backticks when in strings are evaluated as commands. Since there are no commands made only of uppercase letters, the bits in backticks do nothing and aren't included in the output.

If we can't assume input is uppercase, the same method can be adapted to force it to uppercase:

Zsh, 26 bytes

<<<${(L)${(eU)1//[][]/\`}}

Attempt This Online!


Zsh, 21 bytes

<<<${1//[][][a-z]#?/}

Attempt This Online!

A less interesting alternative that uses the equivalent of the \W\w*. regex method used by some other answers: [][] matches any square bracket, then [a-z] any letter (# means "0 or more times"), then ? matches any single character.

Must be run with --extendedglob to enable the # pattern feature.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Great answer. More useful than the zsh manual on the subject of pattern matching \$\endgroup\$
    – roblogic
    Sep 1, 2021 at 23:09
6
\$\begingroup\$

brainfuck, 96 89 71 bytes

-25(!) bytes thanks to Daniel Cristofani

Uses () as brackets.

,[[>+>+<<-]+++++[>--------<-]>[-[[-]>>[<]<[.<<]]]>[>-[++>]<[<]]>[-]<<,]

Try it online!

This is the most complex brainfuck I've ever written and I had quite a few troubles with getting the pointer back to a common position after branches, so I suspect there is some room for optimization.

With some comments:

                              tape layout: _; input1; input2; parity flag
,[                            while loop: runs as long as there is input
  [>+>+<<-]                   make two copies of the input to the right
  +++++[>--------<-]>         subtract 40 from the first copy
  [-[                         if the result is not 0 or 1:
    [-]                         set first copy to 0
    >>[<]<[.<<]                 print second copy is not set
                                pointer is now at _
  ]]
  >[                          if the pointer is at input1
    >-[++>]<[<]                 toggle the parity flag
  ]                  
  >[-]<<                      set second copy to 0
,]

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ +1 I really like the [--[ check for both brackets. Before using my compiler, I had a go at it by hand and gave up needing to constantly copy a flag cell. Of course, using [<] also shows a neater tape layout. \$\endgroup\$ Sep 3, 2021 at 0:17
  • 1
    \$\begingroup\$ This is a good start. But yeah, it could be shorter. Here's a 71-byte version. The layout here is _; input1; input2; parity, and I use movement rather than an explicit flag to control the "brackets or not" choice also. Also, the problem statement allows accepting parentheses rather than square brackets, and that saves 8. \$\endgroup\$ Sep 16, 2021 at 5:25
  • 1
    \$\begingroup\$ @DanielCristofani Thanks a lot for your suggestions! I will include once I managed to understand them fully ;) \$\endgroup\$
    – ovs
    Sep 16, 2021 at 10:14
  • \$\begingroup\$ @ovs Excellent. Let me know if there's anything I can help clarify. \$\endgroup\$ Sep 17, 2021 at 4:56
4
\$\begingroup\$

AutoHotKey, 44 bytes

#UseHook
[::
]::
A:=not A
BlockInput,%A%

You need execute it as Administrator permission. And you can always back to normal input status with Ctrl-Alt-Delete if you are in trouble.

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

Pip, 10 bytes

@UW:a^`\W`

Try it online!

Explanation

The key observation is that the two types of brackets don't need to be distinguished...

    a       First command-line argument
     ^`\W`  Split on this regex (any non-word character, i.e. a bracket)
 UW:        Unweave (the : is needed for precedence reasons, unfortunately)
@           Take the first of the unweave results

Unweave turns a list like [1 2 3 4 5] into [[1 3 5] [2 4]], so @UW applied to the split results gives every other result, starting with the first.

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

JavaScript, 27 26 bytes

Using pajonk's RegEx replacement approach; be sure to +1 them if you're +1ing this.

s=>s.replace(/\W\w*./g,``)

Try it online!

Original, 44 bytes

Adaptation of my Japt solution.

s=>s.split(/\W/).filter((_,y)=>++y%2).join``

Try it online!

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

C (gcc), 55 52 bytes

-3 thanks to dingledooper.

Scans through the string and increments a even-starting depth counter, printing any characters on an even depth: as the input is guaranteed to be balanced, the starting depth will always be an even number. Uses Jonah's trick of only scanning for brackets regardless of direction.

l;f(char*s){for(;*s;s++)*s>96?l%2||putchar(*s):l++;}

Try it online!

\$\endgroup\$
5
  • \$\begingroup\$ 52 bytes \$\endgroup\$ Sep 1, 2021 at 6:41
  • \$\begingroup\$ You rely on undefined behavior since l needs to be initially even and f is furthermore not reusable (see codegolf.meta.stackexchange.com/questions/4939/…). Also, you write to stdout yet have not defined an entire program. \$\endgroup\$ Sep 3, 2021 at 0:25
  • 1
    \$\begingroup\$ @JonathanFrech Functions writing to stdout is allowed \$\endgroup\$ Sep 21, 2021 at 13:31
  • \$\begingroup\$ @JonathanFrech Since the input is always guaranteed to have a balanced number of braces the function is reusable. It only breaks when given an invalid input. \$\endgroup\$
    – Wheat Wizard
    Sep 21, 2021 at 14:35
  • \$\begingroup\$ @WheatWizard In my understanding, it still is a function and not a program writing to stdout which I thought was against the rules (since main typically requires three extra bytes). \$\endgroup\$ Jan 19, 2022 at 9:13
3
\$\begingroup\$

Haskell, 50 bytes

f(h:t)=[h|h>']',even$sum[1|b<-t,b<'a']]++f t
f x=x

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Vyxal K, 24 bytes

Thanks to exedraj, emanresu A and hyper-neutrino for guiding me through my Vyxal journey's beginning.

ƛ91≠*;ƛ93≠*;'[¥¬|¥¬£];C∑

Try it Online!

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

JavaScript (Node.js), 46 bytes

x=>[...x].filter(x=>(z^=b=x>'z')>b,z=1).join``

Try it online!

Port of dingledooper's answer thanks to dingledooper.

JavaScript (Node.js), 51 bytes

x=>x.replace(/[{}]([^{}]*)/g,(a,b)=>i++%2?b:'',i=0)

Try it online!

This makes use of the fact that after an even amount of open or close brackets, the bit of the string up until the next bracket should be kept. After an odd amount, it shouldn't. For example, on the demo input string, the following happens:

Full:    abc[d[fgijk]nopq]rst[u[v[[w]]]xy[[[z]]]]
Valid:   abc  [fgijk     ]rst  [v [w ]   [ [z ] ]
Invalid:    [d      ]nopq    [u  [  ] ]xy [  ] ]

We just smoosh the valid half together, remove all the brackets, and we have our answer!

\$\endgroup\$
2
  • \$\begingroup\$ I'm not particularly good at JS, but perhaps this works for 46? \$\endgroup\$ Sep 1, 2021 at 2:27
  • \$\begingroup\$ @dingledooper Nice, thanks! \$\endgroup\$
    – emanresu A
    Sep 1, 2021 at 2:28
2
\$\begingroup\$

APL (Dyalog Classic), 22 bytes

{((~≠\⍵∊'[]')/⍵)~'[]'}

Try it online!

Explained

{                    }   ⍝ Monadic function, takes string on left
      ⍵∊'[]')            ⍝ Boolean mask for characters which are braces
 ((~≠\                   ⍝ Scan the mask by not-equal and negate (Mask for characters that is needed to kept with braces)
             /⍵)         ⍝ Filter the input using the scanned mask
                ~'[]'    ⍝ Remove the braces

Try it online!

APL (Dyalog Classic), 24 bytes

{((~2|+\⍵∊'[]')/⍵)~'[]'}

Try it online!

Monadic function, takes the string on right

Approaches in array oriented languages are really neat

\$\endgroup\$
4
  • \$\begingroup\$ You can replace the 2|+\ with a scan by XOR (^\ I believe) \$\endgroup\$ Sep 1, 2021 at 2:52
  • \$\begingroup\$ @Dudecoinheringaahing doesn't work I think (I have managed to golf 2 more bytes by bubbler new approach) \$\endgroup\$
    – Wasif
    Sep 1, 2021 at 3:04
  • \$\begingroup\$ @Dudecoinheringaahing There's no bitwise XOR built-in. ≠\ does the job for booleans (which is what ~:/\ does in J). \$\endgroup\$
    – Bubbler
    Sep 1, 2021 at 5:29
  • \$\begingroup\$ The commute operator can be helpful in reducing the number of parenthesis, by moving the simple argument of a function to the left: tio.run/##SyzI0U2pTMzJT9dNzkksLs5M/v@/… \$\endgroup\$
    – ovs
    Sep 1, 2021 at 8:04
2
\$\begingroup\$

jq, 19 bytes

gsub("\\W\\w*.";"")

Uses the regular expression from tsh's answer.

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Nice! Can you edit it into this please, and I'll start a bounty in two days when the question's old enough. \$\endgroup\$
    – emanresu A
    Sep 1, 2021 at 7:57
2
\$\begingroup\$

Charcoal, 16 bytes

FS¿№βιF¬﹪Lυ²ι⊞υι

Try it online! Link is to verbose version of code. Explanation: Prints lowercase letters unless an odd number of other characters have been recorded.

Alternative solution, also 16 bytes:

⪫Φ⪪⪫⪪S]¦[¦[¬﹪κ²ω

Try it online! Link is to verbose version of code. Explanation: Replaces ]s with [s, then splits on [s and outputs alternate elements.

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

Haskell, 66 61 bytes

f(x,y)c=(x-sum[x+x|c>'z'],y++[c|c<'{',x>0])
snd.foldl f(1,"")

Try it online!

Haskell doesn't really do regex.

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

Python 3, 40 bytes (using regex)

lambda s:re.sub("\W\w*.","",s)
import re

Try it online!

Version without lambda, 44 bytes

import re
print(re.sub("\W\w*.","",input()))

Try it online!

Thanks to @emanresu A for the lambda version

\$\endgroup\$
4
  • 1
    \$\begingroup\$ 40 with a lambda \$\endgroup\$
    – emanresu A
    Sep 1, 2021 at 9:24
  • \$\begingroup\$ How does this work with having the import after re is used? I haven't seen this before \$\endgroup\$ Sep 2, 2021 at 12:19
  • 1
    \$\begingroup\$ @JamesWhiteley It is not important weather the import is made before or after the definition of the lambda function. However, it is more convenient for me to do so because I can put f= in the header in TIO as it isn't counted in the byte count \$\endgroup\$
    – Jakque
    Sep 2, 2021 at 13:38
  • 1
    \$\begingroup\$ @JamesWhiteley, re isn't used until the lambda is called, which happens after the import in the TIO. Try moving the import to the end of the footer and it will error as you expect. \$\endgroup\$
    – Shaggy
    Sep 3, 2021 at 9:12
2
\$\begingroup\$

K (ngn/k), 12 bytes

{x&=\x>:93}#

Try it online!

Takes advantage of the input restrictions, i.e. only having to deal with lower cased characters and [] as the brackets.

  • {...}# set up a filter, removing items from the (implicit) input that do not match the criteria in {...}
    • x>:93 determine which characters in the input are letters, updating x inplace (ASCII codes for [] are 91 93, a..z are 97..122)
    • =\ do an equals-scan over this (characters at an even level of nesting become 1, otherwise are 0)
    • x& take the logical and, essentially asking "is this a letter AND is it at even level of nesting?"
\$\endgroup\$
2
\$\begingroup\$

Ly, 37 bytes

1s>ir['aL:[pfpl!sp0]p![pl[p:o0]pp0]p]

Try it online!

This code takes advantage of the input constraints that the characters will only come from the set of characters a-z and [ or ]. Which means checking to see if the codepoint is less than the codepoint for a is sufficient to identify the brackets. It also relies on the constraint that only valid sequences of open and close brackets will given. That allows each bracket to be a "on/off" toggle for the print setting, since it doesn't matter whether it's an open or close, it will always change the even/odd state of the accumulated groupings.

1s                                    -- Set "true" as initial print boolean state
  >                                   -- Change to a clean stack
   ir                                 -- Read all input as codepoints, reverse stack
     [                              ] -- Loop to process each input codepoint
      'aL                             -- Compare top of stack to "a"
         :[p      0]p                 -- if/then, true is codepoint is "[" or "]"
            fp                        -- Pull codepoint forward and delete
              l!sp                    -- Flip "on/off" boolean print state 
                     ![p         0]p  -- if/then, true if codepoint is "a-z"
                        l             -- Load print boolean state
                         [p  0]p      -- if/then, true if we should print the character 
                           :o         -- Duplicate the codepoint and print one copy
                                p     -- Delete the current codepoint from the stack
\$\endgroup\$
2
\$\begingroup\$

brainfuck, 439 bytes

,[>[-]>[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>[-]>[-]<<<<[->>>+>+<<<<]>>>>[-<<<<+>>>>]<[-<->][-]>[-]<<[->+>+<<]>>[-<<+>>][-]+<[[-]>[-]<]>[[-]>[-]+<<<<<<[->>>>>>[-]<<<<<<]>>>>>>[-<<<<<<+>>>>>>]<<<<+>>>]<<++>[-]+<[[-]>[-]<]>[[-]>[-]+<<<<<[->>>>>[-]<<<<<]>>>>>[-<<<<<+>>>>>]<<<+>>]<[-]+<[[-]>[-]<]>[[-]>[-]>[-]<<<<<[->>>>+>+<<<<<]>>>>>[-<<<<<+>>>>>][-]+<[[-]>[-]<]>[[-]<<<<.>>>>]<<]<<,]

Try it online!


Generated using a self-written yet poorly optimizing brainfuck compiler still under development. Its brainfuck macro assembler source code without the prelude can be seen below. I am certain a carefully layed out tape together with hand-written brainfuck would dramatically improve this byte count.

(macro ppcg233884 () (
    ; define parity cell
    (let:nve $parity 0 (
        ; read in character stream
        (let:nve $char 0 (
            (getc:w $char)
            (while:re $char (

                ; check if it is a bracket and update parity
                (let:nve $wasbracket 0 (
                    (let:nve $bracket 91 (
                        ; '['
                        (sub:ra $char $bracket)
                        (ifnot:re $bracket (
                            (not:a $parity)
                            (inc:a $wasbracket)))
                        ; ']'
                        (inc:a $bracket)
                        (inc:a $bracket)
                        (ifnot:ze $bracket (
                            (not:a $parity)
                            (inc:a $wasbracket)))))

                    ; only print on even parity when it was not a bracket
                    (ifnot:ze $wasbracket (
                        (ifnot:re $parity (
                            (putc:r $char)))))))

                (getc:w $char)))))))))

(macro main () (
    (ppcg233884)))
\$\endgroup\$
5
  • \$\begingroup\$ Oh hey, I'm working on a BF compiler thing too! \$\endgroup\$ Sep 2, 2021 at 13:33
  • \$\begingroup\$ @BrowncatPrograms Intriguing. Do you have a (partial) write up so one may look at it? If you are interested in my Brainfuck Compiler Project, I now blogged about it: blog.jfrech.com/248 \$\endgroup\$ Sep 4, 2021 at 13:09
  • \$\begingroup\$ I don't have much written about it yet, but it uses an assembly-like syntax. I've got it half working at the moment, I've finished the parser (still working on some optimizations), and just need to get the actual transpilation part written. \$\endgroup\$ Sep 4, 2021 at 14:46
  • \$\begingroup\$ @BrowncatPrograms Did you implement jump instructions? I found traditional assembler does not transpile very well to brainfuck since there program text is not embedded in the tape. \$\endgroup\$ Sep 5, 2021 at 22:11
  • \$\begingroup\$ No, that's the main place it's different from assembly. Control flow uses if and while instructions, and instead of functions there's just macros. \$\endgroup\$ Sep 6, 2021 at 0:00
2
\$\begingroup\$

05AB1E, 6 bytes

Aм¡ιн˜

I/O as a list of characters. If a nested list output is allowed, the trailing ˜ could be removed.

Try it online or verify all test cases.

Explanation:

A       # Push the lowercase alphabet
 м      # Remove all these letters from the (implicit) input-list
  ¡     # Split the (implicit) input-list on the remaining characters ["[","]"]
   ι    # Uninterleave this list of lists into two parts
    н   # Only leave the first part of sublists
     ˜  # Flatten this nested list into a single list of characters
        # (after which it is output implicitly as result)

(Could also work for mixed cased letters by replacing A with á.)

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

V (vim), 19 bytes

Thanks to Aaron Miller for this two bytes shorter version.

äh:s/]/[/g
òf[df[òx

Try it online!


V (vim), 21 bytes

xPP:s/]/[/g
òf[df[ò0x

Try it online!

Explanation

xPP       " Duplicate initial character,
          "     since `f[` would else skip it.
          "     If the input is empty, error out.
:s/]/[/g  " Unify all brackets to `[`.
ò         " As long as necessary,
 f[       "     keep everything until even `[` and
 df[      "     discard everything until odd `[`.
ò         " End the loop.
0x        " Remove the duplicate character.
\$\endgroup\$
2
2
\$\begingroup\$

Curry (PAKCS), 55 bytes

f(h:t)=[h|h>']',0<foldl(*)1[-1|b<-t,b<'a']]++f t
f[]=[]

Try it online!

This is based on Lynn's Haskell answer. There are two difficulties adapting it to Curry however. The first is that curry doesn't have falling through so the case f x=x needs to be replaced* with f[]=[] for an extra byte.

The next is that curry doesn't have sum so we need to replace it with some sort of fold. The most efficient way to do this is to actually make a product instead of a sum since it is way cheaper to check if something is positive than whether it is even.

*: This doesn't actually behave like I would expect. I'm not a curry expert. However in both the expected behavior and the actual behavior it fails so...

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

C (gcc), 66 63 bytes

f(char*s){for(char*z=s,n=0;*z=*s++;*z-91&&*z-93?n%2||++z:++n);}

Try it online!

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

Haskell, 53 bytes


s?(x:r)|x<'a'=(1-s)?r|s>0=s?r|s<1=x:s?r;_?q=q;f=(0?)

Try it online!

\$\endgroup\$

Your Answer

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

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