18
\$\begingroup\$

She said s(he) be(lie)ve(d), he said sbeve.

Input

  • A non-empty string, s. It's guaranteed that s will have only printable ASCII characters and at least one word (defined as [A-Za-z0-9]+) in parentheses, and all parentheses will be closed respectively.

Output

  • A string containing all non-whitespace characters (whitespaces are defined as spaces, tabs, carriage returns, new lines, vertical tabs and form feeds characters) that are not in parentheses.

Test cases

Input -> Output
s(he) be(lie)ve(d) -> sbeve
s(h3) (1s) br(0k)3n -> sbr3n
(I) (K)now (Ill) Be
(My) Best (Self) -> nowBeBest
sho(u)lder (should)er
s(ho)u(ld)er s(h)ould(er) -> sholderersuersould
p(er)f(ection) -> pf
(hello) (world) ->               

The last output is an empty string.

This is so shortest code in bytes wins.

\$\endgroup\$
20
  • 4
    \$\begingroup\$ Are all whitespace characters guaranteed to be spaces? \$\endgroup\$ Mar 8, 2020 at 16:58
  • 1
    \$\begingroup\$ I think all answers so far assumed whitespaces were limited to spaces due to the examples :( \$\endgroup\$ Mar 8, 2020 at 17:10
  • 2
    \$\begingroup\$ All parentheses will be closed, But will all of them be opened? (: \$\endgroup\$
    – Wheat Wizard
    Mar 8, 2020 at 17:25
  • 2
    \$\begingroup\$ Welcome to code golf :) Using the sandbox can help make your challenges go more smoothly. Also, please consider rewriting your test cases to make them more easy to use (this may also have helped with the spaces confusion). \$\endgroup\$ Mar 8, 2020 at 17:56
  • 6
    \$\begingroup\$ It's guaranteed that s will have only printable ASCII characters. "Printable ASCII" means code points from 32 to 126 (both included), and therefore the only whitespace allowed in the input is the normal space character (so no tabs, newlines etc). Can you confirm, and perhaps edit the challenge text accordingly? \$\endgroup\$
    – Luis Mendo
    Mar 8, 2020 at 23:30

23 Answers 23

5
\$\begingroup\$

Jelly, 11 bytes

>Ƈ⁶Ø(yṣ”)m2

A full program printing the result.

Try it online!

How?

Whitespace printable ASCII characters are "\t\r\n\f\v " and non-whitespace printable ASCII are all greater than ' ', so:

>Ƈ⁶Ø(yṣ”)m2 - Link: list of printable ASCII characters, s
 Ƈ          - filter keep those (characters) for which:
> ⁶         -   greater than literal space character
   Ø(       - literal list of characters ['(', ')']
     y      - translate (replace all '(' with ')')
       ”)   - literal ')' character
      ṣ     - split at
         m2 - modulo-two-slice (every other entry)
            - implicit, smashing print
\$\endgroup\$
4
\$\begingroup\$

05AB1E, 16 bytes

ηʒ„()S¢Æ_}€θJžKÃ

Try it online!, or Verify all test cases


Explanation

η                         - Prefixes of the string 
 ʒ       }                - filter these when...
  „()S¢                   - the counts of ( and ) characters 
       Æ_                 - are the same
          €θ              - get the last character from each of these prefixes
            J             - Join all these last characters
             žKÃ          - and remove any that aren't in [a-zA-Z0-9]
\$\endgroup\$
4
\$\begingroup\$

Retina, 11 bytes

\(.*?\)|\s

(Note the trailing newline in the code).

Try it online!

How it works

                 Replace either
  .*             a sequence of characters
\(   \)          in parentheses,
    ?            matched non-greedily,
       |         or
        \s       any whitespace character
                 by nothing
\$\endgroup\$
3
\$\begingroup\$

Bash + GNU utilities, 36 32 28 bytes

xargs|sed 's/([^)]*)\|\s//g'

Try it online!

Thanks to @user41805 for 4 bytes!

\$\endgroup\$
2
  • \$\begingroup\$ I believe xargs can take the place of tr \$\endgroup\$
    – user41805
    Mar 10, 2020 at 17:46
  • \$\begingroup\$ @user41805 Thank you -- great trick1 \$\endgroup\$ Mar 11, 2020 at 0:55
2
\$\begingroup\$

SNOBOL4 (CSNOBOL4), 119 bytes

 I =INPUT
S I ARB . L '(' ARB ')' REM . I :F(W)
 O =O L :(S)
W O NOTANY(&UCASE &LCASE 84 ** 9) ='' :S(W)
 OUTPUT =O
END

Try it online!

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

Jelly, 12 bytes

e€Ø(œpm2FfØB

Try it online!

A monadic link taking and returning a Jelly string. Now handles other whitespace characters.

Alternative 12 bytes

Ø(yṣ”)m2FfØB

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ Fails the test cases containing newline characters. \$\endgroup\$ Mar 8, 2020 at 17:27
  • \$\begingroup\$ @JonathanAllan to be fair they weren’t there until 9 minutes ago! \$\endgroup\$ Mar 8, 2020 at 17:34
  • \$\begingroup\$ They were there from revision 1, just not that obvious. \$\endgroup\$ Mar 8, 2020 at 17:36
  • \$\begingroup\$ @JonathanAllan ok, thanks. Fixed. \$\endgroup\$ Mar 8, 2020 at 17:37
2
\$\begingroup\$

APL+WIN, 25 bytes or 30 bytes

Prompts for string.

((~x∨≠\x←s∊'()')/s←⎕)~' '

Try it online! Courtesy of Dyalog Classic

If I now have to handle none alphanumeric characters this works for 5 extra bytes in APL+WIN but will not work in Dyalog Classic so no TIO

((~x∨≠\x←s∊'()')/s←⎕)~⎕av[⍳33]
\$\endgroup\$
3
  • \$\begingroup\$ Fails the test cases containing newline characters. \$\endgroup\$ Mar 8, 2020 at 17:27
  • \$\begingroup\$ @JonathanAllan I have modified my code to handle the newline character but the spec seems to be continually evolving. I think I will bow out rather than trying to keep up! \$\endgroup\$
    – Graham
    Mar 8, 2020 at 17:59
  • \$\begingroup\$ You can always delete and come back later, but I think most issues have been ironed out. Printable ASCII in s, balanced parentheses, whitespace are ordinals 9, 10, 11, 12, 13, and 32. \$\endgroup\$ Mar 8, 2020 at 18:04
2
\$\begingroup\$

05AB1E, 12 bytes

ŒʒÁ„)(å}KžKÃ

Try it online!

Π              # substrings 
 ʒ     }        # filter, keep each substring if:
  Á             #  after being rotated right
   „)(å         #  it contains ")("
        K       # remove those substrings from the input
         žKÃ    # keep only characters in [a-zA-Z0-9]
\$\endgroup\$
3
  • \$\begingroup\$ Nice didn't realise that K would work like that, I didn't try it because I thought it would remove the text in between brackets too.. but I guess it applies each consecutively? \$\endgroup\$ Mar 9, 2020 at 12:12
  • 1
    \$\begingroup\$ Yup, K (and similar operators like :, .: and .;) applies substitutions one by one. \$\endgroup\$
    – Grimmy
    Mar 9, 2020 at 12:13
  • 1
    \$\begingroup\$ Since my 10-byter using the split and uninterleave builtins was quite different from both of your answers, I decided to post it as a separated answer. \$\endgroup\$ Mar 10, 2020 at 7:18
2
\$\begingroup\$

Stax, 11 bytes

û┼╢╕jN&╪º╛╘

Run and debug it

Unpacked:

"\(.*?\)| "zR

this is just a simple regex replace. It replaces all strings that match /\(.*?\)| / with z (an empty string)

\$\endgroup\$
1
  • \$\begingroup\$ You can deal with whitespace by splitting on spaces, j at the end. The resulting segments are implicitly concatenated when printed, taking you down to 10 bytes. \$\endgroup\$ Apr 28, 2020 at 20:03
2
\$\begingroup\$

Perl 5 + -lF/\(\w+\)|\s+/ -M5.10.0, 5 bytes

say@F

Try it online!

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

05AB1E, 10 11 bytes

„()S¡ιнJʒð›

+1 byte as bug-fix (žu to „() and žKÃ to ʒð›), since apparently all printable ASCII + whitespaces are valid input-characters, instead of only alphanumeric, whitespaces, and parenthesis..

Try it online or verify all test cases.

Explanation:

„()S         # Push string "()", and split it to a list of characters: ["(",")"]
    ¡        # Split the (implicit) input-string by that
     ι       # Uninterleave this list
      н      # Only keep the first inner list
       J     # Join it together to a single string
        ʒ    # Filter the characters in this string by:
         ð›  #  Check if the character is larger than a space " " (by ASCII codepoint)
             # (after which the result is output implicitly)
\$\endgroup\$
4
  • \$\begingroup\$ We're only supposed to remove substrings wrapped in (), aren't we? \$\endgroup\$
    – Shaggy
    Sep 15, 2020 at 11:14
  • \$\begingroup\$ @Shaggy And remove all whitespaces. But I think the reason you're asking is due to the ()<>[]{}? The input is guaranteed to only contain alphanumeric characters, whitespaces, and parenthesis. So using the builtin žu is 1 byte shorter than string „()/„)(. \$\endgroup\$ Sep 15, 2020 at 11:38
  • \$\begingroup\$ From the spec: "It's guaranteed that s will have only printable ASCII characters". Maybe it changed since you posted this, though? \$\endgroup\$
    – Shaggy
    Sep 15, 2020 at 11:58
  • \$\begingroup\$ @Shaggy Hmm, I guess you're indeed right. I do remember the specs changed A LOT with this challenge, but my answer was posted after those changes.. In that case the other two 05AB1E answers are invalid as well, though. Since all three of us use žKÃ.. :/ Ah well, I've fixed my answer. \$\endgroup\$ Sep 15, 2020 at 12:20
1
\$\begingroup\$

Japt, 12 bytes

r"%s|%(.*?%)

Try it

\$\endgroup\$
2
  • \$\begingroup\$ Why not r" |%(.*?%)? \$\endgroup\$
    – Gymhgy
    Mar 15, 2020 at 21:21
  • \$\begingroup\$ @EmbodimentofIgnorance, because that would only remove literal spaces and not newlines, tabs, etc.. \$\endgroup\$
    – Shaggy
    Sep 15, 2020 at 11:13
1
\$\begingroup\$

Python 3, 47 45 bytes

Saved 2 bytes thanks to FryAmTheEggman!!!

lambda s:re.sub(r"\(\w+\)|\s","",s)
import re

Try it online!

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

Charcoal, 18 bytes

Φθ∧›ι ⁼№…θ⊕κ(№…θκ)

Try it online! Link is to verbose version of code. Explanation:

 θ                  Input string
Φ                   Filtered where
    ι               Current character
   ›                Is not whitespace
  ∧                 Logical And
       №            Count of
            (       Open parentheses
        …θ⊕κ        In input string so far (inclusive)
      ⁼             Equals
             №      Count of
                 )  Close parentheses
              …θκ   In input string so far (exclusive)
\$\endgroup\$
1
\$\begingroup\$

Perl 5 -p0, 15 bytes

s/\s|\(.*?\)//g

Try it online!

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

sed, 32 31 bytes

:l;s/([^)]*)\|\s//g;N;s/\n//;tl

Try it online!

Shaved off one byte by removing the -E option and just using basic regular expressions, surprisingly :-) .

sed is almost perfect for this challenge. The only issue is that sed is a stream editor, processing one line at a time: the trailing newline on each line is not processed, which doesn't make it straightforward to delete any newline characters.

So here's how this script does it:

:l
   Label we can jump to later.

s/([^)]*)\|\s//g
   Delete all parenthetical expressions and whitespace before the first newline.

N
   If we're not at the last line, append the next line to the pattern space.  (The next line is appended immediately _after_ the \n at the end of the previous line.  That \n is still there, now in the middle of the pattern space, where it's available for processing by sed.)

s/\n//
    Delete a \n in the middle of the pattern space, if any.  (There will be one if we weren't at the last line in the previous step already.)

tl
    If the last command found a \n to delete, jump back to label l, and do it again!
\$\endgroup\$
2
  • \$\begingroup\$ Hint: there's a flag in GNU sed (since 4.2.2 or something) that slurps all those newline-delimited lines \$\endgroup\$
    – user41805
    Mar 10, 2020 at 17:44
  • \$\begingroup\$ @user41805 Thanks, I'll check it out. I thought I reviewed all the sed flags, but maybe I was looking at old documentation, or maybe I missed it. \$\endgroup\$ Mar 11, 2020 at 4:27
1
\$\begingroup\$

C (gcc), 70 bytes

f(char*s){for(;*s;)s=*s-40?isalnum(*s)&&putchar(*s),s+1:strchr(s,41);}

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Suggest index() instead of strchr() \$\endgroup\$
    – ceilingcat
    Mar 9, 2020 at 20:45
1
\$\begingroup\$

Red, 52 bytes

func[s][parse trim/all s[any[to"("remove thru")"]]s]

Try it online!

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

JavaScript (Node.js), 30 bytes

s=>s.replace(/\(.*?\)|\s/g,"")

Try it online!

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

APL (Dyalog Extended), 21 19 bytes

∊⊢⊆⍨<>(≠\∨⊢)⍤∊∘'()'

Try it online!

How it works

∊⊢⊆⍨<>(≠\∨⊢)⍤∊∘'()'  ⍝ Input: string s
             ∊∘'()'  ⍝ Boolean vector (1 if a member of '()')
      (≠\  )⍤        ⍝ Scan by boolean XOR
                     ⍝ (gives 1 between '()'s, including '(' but not ')')
         ∨⊢          ⍝ Include back ')'
     >               ⍝ Bitmask indicating negation of the above,
    <                ⍝ plus each char not being whitespace
∊⊢⊆⍨                 ⍝ Filter s by the bitmask above

Boolean filtering uses this APL golfing tip.

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

Gema, 7 characters

(*)=
 =

Sample run:

bash-5.0$ gema '(*)=; =' <<< 's(he) be(lie)ve(d)'
sbeve

Try it online! / Try all test cases online!

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

Kotlin, 75 bytes

{fold(""){a,v->when(v){')'->a.takeWhile{it!='('}
in " \r\n"->a
else->a+v}}}

Try it online!

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

Pip, 14 bytes

aRMw,`\(.+?\)`

Try it online!

Unweave works really well in this solution.

-2 bytes from DLosc, with the first documented use of , for Regex alternation!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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