Test if a string is parenthesly balanced

We call a parens group the open paren (, its matching close paren ) and everything inside them.

A parens group or string is called parenthesly balanced if it contains either nothing or only 2 parenthesly balanced parens groups.

For example:

The string   "(()())()"      is parenthesly balanced
(    )()       Because it contains exactly 2 parenthesly balanced parens groups
()()          The left one is parenthesly balanced because it contains 2 parenthesly balanced parens groups (balanced because they are empty). The right one is parenthesly balanced because it contains nothing.


Likewise:

The string   "(()(()))()"    is not parenthesly balanced
(      )()     Because it contains a parens group that is not parenthesly balanced: the left one
()(  )        The left one is not balanced because it contains a parens group that is not balanced: the right one
()         The right one is not balanced because it only contains one balanced group.


So, a parenthesly balanced string or parens group should either:

• Contain nothing at all.
• Or contain only and exactly 2 parenthesly balanced parens groups. It should contain nothing else.

Your task is to write a function or program that checks if a given string is a parenthesly balanced one or not.

Input:

Input will be a string or list of characters or something similar. You can assume that the string will only consist of the characters '(' and ')'. You can also assume that each open paren ( will have its matching close paren ), so don't worry about strings like "(((" or ")(" or "(())("...

Note: As mentioned by @DigitalTrauma in his comment bellow, it's ok to subtitute the () combo by other characters (such as <>, [], ...), if it's causing additional work like escaping in some languages

Output:

Anything to signal whether the string is parenthesly balanced or not (true or false, 1 or 0, ...). Please include in your answer what your function/program is expected to yield.

Examples:

""                                        => True
"()()"                                    => True
"()(()())"                                => True
"(()(()(()())))(()())"                    => True
"(((((((()())())())())())())())()"        => True
"()"                                      => False
"()()()"                                  => False
"(())()"                                  => False
"()(()(())())"                            => False
"(()())(((((()())()))())())"              => False
"()(()()()())"                            => False
"()(()(()())()())"                        => False


The last two examples really made a difference!

Best of luck!

• Anything to signal whether the string is parenthesly balanced or not Is consistent output required, i.e. only two values? – Luis Mendo Aug 1 '18 at 20:49
• @LuisMendo Could be categories. i.e. truthy values to signal truthiness and falsy values to signal otherwise. So there could be more, but it should be consistent nevertheless. – ibrahim mahrir Aug 1 '18 at 20:54
• Is it okay if I take a binary list as an input? For instance, "(()())()" would be represented as [0, 0, 1, 0, 1, 1, 0, 1]. This would remove the necessity to convert the input to character code and then subtracting. – JungHwan Min Aug 1 '18 at 23:13
• Related question: codegolf.stackexchange.com/questions/166457/… – Windmill Cookies Aug 2 '18 at 10:05
• @WindmillCookies I don't see how that's related to this one. Totally different things. Even the concept is different. – ibrahim mahrir Aug 2 '18 at 12:05

Japt v2, 20 bytes

V="()"V¥iU1 eViV²1 V


Test it online!

Everyone misunderstood the challenge at first and though that each pair of parentheses had to contain an even number of sub-pairs, when in fact the challenge actually asks for 0 or 2 sub-pairs. So here's my revised answer, using the same technique as before.

We can still solve the challenge with recursive replacement. The thing is, instead of just removing all occurrences of ()(), we need to make sure that there's nothing else in the same wrapper besides the ()() (in other words, no ()()()() or anything like that). We can do this by recursively replacing (()()) with ().

The new problem is that the input itself does not have one pair of outer parentheses (as that would make it not a parenthesly balanced string), forcing us to wrap it in an extra pair to fully reduce it. Finally, the end result for balanced strings is now () instead of the empty string, so we check for equality rather than just taking logical NOT of the output.

sed 4.2.2, 30

:
s/(()())/()/
t
/^()()$\|^$/q1


This returns a shell exit code of 1 for True and 0 for False.

:               # label
s/(()())/()/    # replace "(()())" with "()"
t               # jump back to label if above replacement matched
/^()()$\|^$/q1  # exit code 1 if remaining buffer is exactly "()()" or empty
# otherwise exit with code 0


Perl 5 -lp, 24 22 bytes

$_=/^((<(?1)?>){2})?$/


Try it online! Link includes test cases. Edit: Saved 2 bytes thanks to @JoKing. Explanation: Just a recursive regex. The outer capturing group represents a balanced string as a < followed by an optional balanced string followed by a >, twice. Note that most of the other answers are able to use ()s but this costs an extra two bytes:

$_=/^(($$(?1)?$$){2})?$/


Try it online! Link includes test cases.

• Since you can use other pairs of brackets, you can save two bytes by using <> – Jo King Aug 2 '18 at 9:39
• @JoKing Almost all of the other answers were able to use ()s so I didn't think it was a fair comparison, however I see @ngn's APL answer also uses <>s so I've updated this one. – Neil Aug 7 '18 at 10:29

6502 machine code routine, 48 bytes

A0 00 84 FD A2 00 B1 FB F0 0E C8 C9 29 18 F0 06 8A 48 E6 FD 90 EE B0 0A E0 01
90 06 E0 02 38 D0 01 18 A5 FD F0 09 C6 FD 68 AA E8 B0 F5 90 D7 60


Expects a pointer to a string in $fb/$fc which is expected to only contain ( and ). Clears C (Carry) flag if the string is "paranthesely balanced", sets it otherwise (which is a typical idiom on the 6502, set carry "on error"). Does nothing sensible on invalid input.

Although the algorithm is recursive, it doesn't call itself (which would need more bytes and make the code position dependent) but instead maintains a recursion depth itself and uses "simple" branching.

Commented disassembly

; function to determine a string is "paranthesly balanced"
;
; input:
;   $fb/$fc: address of the string
; output:
;   C flag set if not balanced
; clobbers:
;   $fd: recursion depth ; A,X,Y .isparbal: A0 00 LDY #$00            ; string index
84 FD       STY $FD ; and recursion depth .isparbal_r: A2 00 LDX #$00            ; set counter for parantheses pairs
.next:
B1 FB       LDA ($FB),Y ; load next character F0 0E BEQ .done ; end of string -> to final checks C8 INY ; increment string index C9 29 CMP #$29            ; compare with ')'
18          CLC                 ; and reset carry
F0 06       BEQ .cont           ; if ')' do checks and unwind stack
8A          TXA                 ; save counter ...
48          PHA                 ; ... on stack
E6 FD       INC $FD ; increment recursion depth 90 EE BCC .isparbal_r ; and recurse .cont: B0 0A BCS .unwind ; on previous error, unwind directly .done: E0 01 CPX #$01            ; less than one parantheses pair
90 06       BCC .unwind         ; -> ok and unwind
E0 02       CPX #$02 ; test for 2 parantheses pairs 38 SEC ; set error flag D0 01 BNE .unwind ; if not 2 -> is error and unwind 18 CLC ; clear error flag .unwind: A5 FD LDA$FD             ; check recursion depth
F0 09       BEQ .exit           ; 0 -> we're done
C6 FD       DEC $FD ; otherwise decrement 68 PLA ; get "pair counter" ... AA TAX ; ... from stack E8 INX ; and increment B0 F5 BCS .unwind ; continue unwinding on error 90 D7 BCC .next ; otherwise continue reading string .exit: 60 RTS  Example C64 assembler program using the routine: Online demo Code in ca65 syntax: .import isparbal ; link with routine above .segment "BHDR" ; BASIC header .word$0801           ; load address
.word   $080b ; pointer next BASIC line .word 2018 ; line number .byte$9e             ; BASIC token "SYS"
.byte   "2061",$0,$0,$0 ; 2061 ($080d) and terminating 0 bytes

.bss
linebuf:        .res    256

.data
prompt:         .byte   "> ", $0 truestr: .byte "true",$0
falsestr:       .byte   "false", $0 .code inputloop: lda #<prompt ; display prompt ldy #>prompt jsr$ab1e

lda     #<linebuf       ; read string into buffer
ldy     #>linebuf
ldx     #0              ; effectively 256

lda     #<linebuf       ; address of string to $fb/fc sta$fb
lda     #>linebuf
sta     $fc jsr isparbal ; call function bcs isfalse lda #<truestr ldy #>truestr bne printresult isfalse: lda #<falsestr ldy #>falsestr printresult: jmp$ab1e           ; output true/false and exit

; read a line of input from keyboard, terminate it with 0
; expects pointer to input buffer in A/Y, buffer length in X
dex
stx     $fb sta$fc
sty     $fd ldy #$0
sty     $cc ; enable cursor blinking sty$fe             ; temporary for loop variable
getkey:         jsr     $f142 ; get character from keyboard beq getkey sta$2              ; save to temporary
and     #$7f cmp #$20            ; check for control character
bcs     checkout        ; no -> check buffer size
cmp     #$d ; was it enter/return? beq prepout ; -> normal flow cmp #$14            ; was it backspace/delete?
bne     getkey          ; if not, get next char
lda     $fe ; check current index beq getkey ; zero -> backspace not possible bne prepout ; skip checking buffer size for bs checkout: lda$fe             ; buffer index
cmp     $fb ; check against buffer size beq getkey ; if it would overflow, loop again prepout: sei ; no interrupts ldy$d3             ; get current screen column
lda     ($d1),y ; and clear and #$7f            ;   cursor in
sta     ($d1),y ; current row output: lda$2              ; load character
jsr     $e716 ; and output ldx$cf             ; check cursor phase
beq     store           ; invisible -> to store
ldy     $d3 ; get current screen column lda ($d1),y         ; and show
ora     #$80 ; cursor in sta ($d1),y         ;   current row
lda     $2 ; load character store: cli ; enable interrupts cmp #$14            ; was it backspace/delete?
beq     backspace       ; to backspace handling code
cmp     #$d ; was it enter/return? beq done ; then we're done. ldy$fe             ; load buffer index
sta     ($fc),y ; store character in buffer iny ; advance buffer index sty$fe
bne     getkey          ; not zero -> ok
done:           lda     #$0 ; terminate string in buffer with zero ldy$fe             ; get buffer index
sta     ($fc),y ; store terminator in buffer sei ; no interrupts ldy$d3             ; get current screen column
lda     ($d1),y ; and clear and #$7f            ;   cursor in
sta     ($d1),y ; current row inc$cc             ; disable cursor blinking
cli                     ; enable interrupts
rts                     ; return
backspace:      dec     $fe ; decrement buffer index bcs getkey ; and get next key .endproc  V, 21, 20 bytes é(Á)òÓ(“()()…)òø^()$

é(                      " Insert '(' at the beginning of the line
Á)                    " Append ')' at the end
ò         ò         " Recursively...
Ó                  "   Remove...
(                 "     '('
“    …           "     (Limit the part that is removed to this section of the match)
()()            "     '()()'
)          "     ')'
" (effectively, this replaces '(()())' with '()', but it's one byte shorter than the straightforward approach
ø        " Count...
^()$" Lines containing exactly '()' and nothing more  Hexdump: 00000000: e928 c129 f2d3 2893 2829 2829 8529 f2f8 .(.)..(.()().).. 00000010: 5e28 2924 ^()$

• Can you explain your code so I can (hopefully) find a testcase that doesn't work, like I did with @Adàm's answer. – ibrahim mahrir Aug 2 '18 at 11:27
• @ibrahimmahrir Done. – James Aug 2 '18 at 14:49

Brachylog, 28 bytes

Ẹ|~c["(",A,")(",B,")"]∧A;B↰ᵐ


Try it online!

Explanation

                                    --  The string perfectly balanced iff
Ẹ                                   --      the string is empty
|                                  --  or
~c["(",A,")(",B,")"]              --      the string can be written id the format of "($A)($B)"
∧             --          where
A;B ᵐ        --          both A and B
↰         --          are perfectly balanced


C (gcc), 113 bytes

p(a,r,e,n)char*a;{if(*a-40)return 1;for(r=1,e=0;e<2;r&=e++||*a==40)for(r*=n=p(++a);n+=*a++-40?~0:1;);r=r&&*a-40;}


Try it online!

Explanation

p(a,r,e,n)char*a;{   // function and variable declaration
if(*a-40)return 1;  // string does not start with '(', thus is empty
for(r=1,e=0;e<2;    // r: return value, e: group id (look for exactly two groups)
r&=e++||*a==40)     // after the first group, a second shall follow
for(r*=n=p(++a);   // check that the group is itself balanced
n+=*a++-40?~0:1;); // skip group


Try it online!

MATL, 26 25 bytes

oo~tnw52B5LZttnb<]XB10X-


Try it online!

Thanks to @ETHProductions' answer for the "replace (()()) with ()" idea, and @JungHwan Min's question comment for the idea of seeing the brackets as binary digits.

Output is an empty array for truthy, a positive number for falsey - which I think is allowed by OP's comment: "Could be categories. i.e. truthy values to signal truthiness and falsy values to signal otherwise." If it's not, we can add n at the end for +1 byte, to have 0 as truthy output and 1 as falsey output.

o         % Convert the parantheses to their ASCII codes
%  40 for '(', 41 for ')'
o         % Parity - 1 for odd, 0 for even
~         % Not - change 0 to 1 and vice versa, so '(' is now 1 and ')' 0
% Input char array is now a binary array B
% Do-while loop
tn          % Get the length of the array
w           % Bring the array B back on top
52B         % Push the binary value of 52 on stack
%  [1 1 0 1 0 0] (equivalent to '(()())')
5L          % Push the constant [1 0] for '()'
Zt          % Replace the sequence [1 1 0 1 0 0] in array B
%  with [1 0]
tn          % Get the length of the array after replacement
b<          % Has it decreased? If so, continue loop
]       % end loop
% Final value for balanced input will be
%  either [1 0 1 0] for the remaining outer '()()'
%  or an empty array [] for empty '' input
XB        % Convert the final binary array back to decimal
10X-      % Set difference, remove 10 from that result
% Result is [] empty array for balanced input, otherwise
%  some decimal number ≠ 10 for unbalanced input


C# (.NET Core), 78 71 bytes

f=s=>{var r=s.Replace("(()())","()");return r==s?s==""|s=="()()":f(r);}


Try it online!

all(elem[0,2]).foldl(#)[0]
b#'('=0:b
(x:y:z)#_=y+1:z++[x]


Try it online!

I assume it can be golfed much further since it's my first time golfing in haskell, so any tricks or comments are more than welcome.

EDIT - Thanks @nimi for saving 23 bytes (more than 28% of the original submission :)

• Some tips: no need for the () around y+1. As unnamed functions are allowed, you can drop the f=, r[0] is a proper function. Put the base case r b[] at the end and switch to a infix function (say #), then you can use b#_=. You can also change your algorithm slightly by building the list to check for 0s and 2s step by step instead of carrying it around the calls of r in an accumulator r(x:y:z) ... = x : r (...) a with base case r b [] = b. Do the check after the initial call r[0]. All in all 73 bytes. – nimi Aug 2 '18 at 14:37
• ... Try it online!. – nimi Aug 2 '18 at 14:38
• ... or even better: stay with the accumulator and switch to foldl (59 bytes): Try it online!. – nimi Aug 2 '18 at 14:46
• @nimi Thank you very much, exactly the kind of tips I was looking for :) – Vincent Aug 2 '18 at 15:14

JavaScript (ES6), 63 bytes

Takes input as an array of characters. Returns false for parenthesly balanced, true for not parenthesly balanced.

a=>[...a,k=0].some(c=>c<')'?!(a[k]=-~a[k++]):a[k]=~5>>a[k--]&1)


Try it online!

Commented

a =>                     // a[] = input array of characters; we are going to reuse it to
[                      // store the number of parenthesis groups at each depth
...a,                // append all characters
k = 0                // initialize k = current depth to 0 and append a value that will
]                      // be treated as a final closing parenthesis for the root level
.some(c =>             // for each character c in this array:
c < ')' ?            //   if c is an opening parenthesis:
!(                 //     increment the number of groups at the current depth
a[k] = -~a[k++]  //     increment the depth
)                  //     yield false
:                    //   else:
a[k] = ~5          //     make sure that the current depth contains either 0 or 2
>> a[k--]   //     groups, by shifting the 1-complement of 5 (101 in binary)
& 1         //     and testing the least significant bit
//     it resets the number of groups to 0 if the bit is not set
//     otherwise, it forces some() to return true
//     decrement the depth
)                      // end of some()


Recursive, 54 bytes

Using recursive replacements (like in ETHproductions' Japt answer) is however significantly shorter.

Takes input as a string. Returns 1 for parenthesly balanced, 0 for not parenthesly balanced.

f=s=>s==(s=s.split(()()).join())?!s|s=='()()':f(s)


Try it online!

Recursive, 46 bytes

This one throws a recursion error for not parenthesly balanced:

f=s=>!s|s=='()()'||f(s.split(()()).join())


Try it online!

• I'm not that good in JavaScript but could x[k]=-~x[k++] be replaced with x[k]++;k++ or even ++x[k++] ? – Андрей Ломакин Aug 2 '18 at 10:17
• @АндрейЛомакин No, because x[k] is initially undefined and x[k]++ would give NaN, whereas -~undefined gives 1. – Arnauld Aug 2 '18 at 10:20
• @АндрейЛомакин I'm now re-using the input array, so a[k] initially contains a character. But the same logic applies to strings: applying the ++ operator on them yields NaN, but bitwise operators (such as ~) force them to be coerced to 0 beforehand. – Arnauld Aug 2 '18 at 11:33
• Takes javascript to a whole new level. :D – ibrahim mahrir Aug 2 '18 at 11:49

Perl 6,  43 41  37 bytes

{my rule f{$$[<&f>**2]?$$};?/^<&f>**2$|^$/}


Test it

{(my$f)=/$$[<f>**2]?$$/;?/^[<$f>**2]?$/}  Test it {$!=/$$[<!>**2]?$$/;?/^[<$!>**2]?$/}


Test it

Expanded:

{  # bare block lambda with implicit parameter $_$! = # store regex into $! (no need to declare it) / $$[ <!> ** 2 # recurse into regex twice ]? # optionally$$ /; ? # boolify (causes it to be run against$_)

/
^         # beginning of string

<$!> ** 2 # match using regex twice$         # end of string

|           # or

^ \$       # empty string
/
}


R, 71 bytes

f=function(s,r=sub('(()())','()',s,f=T))'if'(r==s,s==''|s=='()()',f(r))


Try it online!

• porting of recursive Japt solution of @ETHproductions
• -2 bytes thanks to @JayCe

Another - longer - solution but interesting for the different approach

R, 85 bytes

g=gsub;!sum(eval(parse(t=g('\\)\$$',')-(',g('\$$','-1)',g('\\(','(2+',scan(,'')))))))


Try it online!

Explanation :

Take the input string and replaces :

'('  with '(2+'
')'  with '-1)'
')(' with ')-('


then evaluates the resulting expression. If it's equal to zero is balanced, otherwise is not. The use of sum is only necessary to handle the empty string case, because its evaluation returns NULL.

e.g.

()(()()) => (2+-1)-(2+(2+-1)-(2+-1)-1) = 0
(()())   => (2+(2+-1)-(2+-1)-1)        = 1

• Save two bytes: f=function(s,r=sub('(()())','()',s,f=T))'if'(r==s,s==''|s=='()()',f(r)) – JayCe Aug 8 '18 at 2:53
• You should put the shorter solution first – ASCII-only Aug 8 '18 at 6:09
• @ASCII-only: you're right, but since it's basically a porting of another solution it seemed like "stealing" :P – digEmAll Aug 8 '18 at 6:36
• @digEmAll Well, in a lot of challenges here most of the challenges do just port another solution – ASCII-only Aug 8 '18 at 6:49

Wolfram Language (Mathematica), 65 bytes

#=={}||{1,1}==(#//.{a___,"(",i:1...,")",b___}/;1!=+i<3:>{a,1,b})&


Try it online!

05AB1E, 1816 13 bytes

…(ÿ)…(()∞„()©:®Q


Port of @ETHproductions's Japt answer to fix the test case ()(()()(()())(()())).

Based on this comment of OP I now use () as truthy value, and anything else as falsey. If both values need to be consistent instead of just one, it would be the old 16-bytes answer instead (…(ÿ)…(()∞„()©:®Q), returning 0 for truthy and 1 for falsey test cases.

Explanation

…(ÿ)             # Take the input (implicitly) and surround it with "(" and ")"
:    # Infinite replacement of:
…(()∞        #  "(()())"    ("(()" mirrored)
„()     #  with "()"
# After the infinite replacement: return the result
# ("()" for truthy; falsey otherwise)


(Old 18-bytes answer which failed for test case ()(()()(()())(()()))..):

ΔD„()∞©6∍å_i®õ.:]Ā

• I think you can use the infinite replace method: „()∞õ:g_. – Adnan Aug 2 '18 at 8:35
• no wait I misunderstood the challenge – Adnan Aug 2 '18 at 8:36
• @Adnan I thought so at first as well, but it fails for test cases containing (()()()()) which should return falsey. Every parenthesis group should contain exactly 0 or 2 inner groups. – Kevin Cruijssen Aug 2 '18 at 8:36
• You can replace '(®')J with …(ÿ). – Adnan Aug 2 '18 at 11:58
• @Adnan Thanks! I knew ÿ existed, but never used it before, so completely forgot about it. – Kevin Cruijssen Aug 2 '18 at 12:02

APL (Dyalog Classic), 27 bytes

3>≢'<<><>>'⎕r'<>'⍣≡1⌽'><',⎕


Try it online!

Prolog, 46 bytes

a-->p,p.
a-->[].
p-->[l],a,[r].
f(X):-a(X,[]).


Uses lists of l and r as input, e.g. "()()" is tested as f([l,r,l,r])..

The first three lines are the grammar of valid strings in Prolog's Definite Clause Grammar syntax. a(A,B). returns true when A is a list which follows the grammar and B is empty. Thus the main function f takes some X and checks whether a(X,[]) holds.

Python 2, 73 71 bytes

f=lambda s,P='(()())':P in s and f(s.replace(P,'()'))or s in['()()','']


Try it online!

brainfuck, 50 bytes

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


Formatted:

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


Expects a string of ( and ) without a trailing newline, and outputs \x01 for true and \x00 for false. (For legibility, you can e.g. add 48 +s before the final . to make it print 1 and 0 instead.)

Try it online

This maintains a stack with the number of groups at each depth, distinguishing characters by parity and checking whether the number of groups is in {0, 2} after each close parenthesis; if the condition is not met, consumes the rest of the input and sets a flag; then checks the condition again at the end of the program.

If we are allowed to terminate the input stream with an odd character, we can omit the final check <[--[>->]] to save 10 bytes. (If \n weren't inconveniently even, I might have proposed this variant as the main answer.)

(We could also save some bytes by changing the output format to \x00 for true and non-\x00 for false, which seems to be allowed (maybe accidentally) by the problem statement as written, but anyway it wouldn't be very interesting, and I prefer not to make that change.)

Python2, 95 94 bytes

f=lambda i:g(eval("(%s)"%i.replace(")","),")))
g=lambda i:len(i)in(0,2)and all(g(j)for j in i)


Try it online!

f() transforms the string into a nested tuple, which it passes to g().

g() recursively navigates the tuple and returns False if any element doesn't have exactly 0 or 2 children.

Saved one byte by using string formatting.

Stax, 13 11 bytes

₧aaS▐îî»Å·╢


Run and debug it

I saved two bytes when I realized the inputs can coincidentally be implicitly evalled as array literals. By removing the double quotes, the input is simplified.

The general idea is to eval the input as an array literal, and recursively map the elements to check parethesly balance. If the final assertion ever fails, then there will be a subsequent pop on an empty stack. In stax, popping with empty stacks immediately terminates the program.

Unpacked, ungolfed, and commented, it looks like this.

        input is implicitly treated as array literals
L       wrap entire input stack in an array
}       terminate the program, the rest is a recursive call target
{Gm     map array on top of the stack by using the recursive call target
%       get the length of the mapped array
02\#    is the length one of [0, 2]?
|c      assert value is truthy, pop if not


Run this one

Java 10, 999695 83 bytes

s->{s="("+s+")";for(var p="";!p.equals(s);s=s.replace("(()())","()"))p=s;return s;}


Port of my 05AB1E answer (so also returns () as truthy and anything else as falsey).

Try it online.

Explanation:

s->{                 // Method with String as both parameter and return-type
s="("+s+")";       //  Surround the input-String between "(" and ")"
for(var p="";      //  Previous-String, starting empty
!p.equals(s)   //  Loop as long as the previous and current Strings differ
;              //    After every iteration:
s=s.replace("(()())","()"))
//     Replace all "(()())" with "()"
p=s;             //   Set the previous String with the current
return s;}         //  Return the modified input-String
//  (if it's now "()" it's truthy; falsey otherwise)


return s; can be return"()".equals(s); if an actual boolean result was required.

• You can save one byte if you just check !s.contains("()()(") – Charlie Aug 2 '18 at 11:39
• @Charlie Thanks, but the code contained a bug anyway, so had to change it. It's now fixed (for the last added falsey test case), and golfed by 4 bytes at the same time. – Kevin Cruijssen Aug 2 '18 at 11:52