Peter’s blog ✴ Week 385 ✴ 3 August 2026

THE WEEKLY CHALLENGE
Lonely words and (outer)

The Perl Camel

Task 2

Outermost parentheses

You are given a valid parentheses string. Write a script to return the string after removing the outermost parentheses of every primitive string in the primitive decomposition of the given string.

Examples


Example 1
Input: $str = '()()()'
Output: ''
Primitive Decomposition: '()' + '()' + '()'

Example 2
Input: $str = '(((())))'
Output: '((()))'
Primitive Decomposition: '(((())))'

Example 3
Input: $str = '(()())(())'
Output: '()()()'
Primitive Decomposition: '(()())' + '(())'

Example 4
Input: $str = '()((()))()'
Output: '(())'
Primitive Decomposition: '()' + '((()))' + '()'

Example 5
Input: $str = '(()(()))(()())'
Output: '()(())()()'
Primitive Decomposition: '(()(()))' + '(()())'

Analysis

There's probably a clever way to do this using regular expressions, but I went for a simpler but lengthier solution which I think is easier to understand..

The main loop in my solution works along the input string, incrementing $depth when it meets a '(' and decrementing it after a ')'. When $depth gets to 0 there have been the same number of '(' and ')' and thus this sequence is an element of the primitive decomposition and it is added to @decomp.

Then each item in @decomp is stripped of its first and last characters, which will be '(' and ')', and the result is added to $output.

Try it 

Your input:



eg: ((()))

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge/385/2

use v5.26;    # The Weekly Challenge - 2026-08-03
use utf8;     # Week 385 - task 2 - Outermost parentheses
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

outermost_parentheses('()()()');
outermost_parentheses('(((())))');
outermost_parentheses('(()())(())');
outermost_parentheses('()((()))()');
outermost_parentheses('(()(()))(()())');
outermost_parentheses('((())))');

sub outermost_parentheses {
    
    my (@parens, $depth, @decomp, $d, $m, $unbalanced, $output);
    
    # initialise
    say qq[\nInput:  '$_[0]'];
    @parens = split('', $_[0]);
    $depth = $d = 0;
    $output = '';
    
    # decompose
    for $m (@parens) {
        next unless $m =~ m|[()]|;
        $depth += ($m eq '(' ? 1 : -1);
        last if $depth < 0;
        $decomp[$d] .= $m;
        $d ++ if $depth == 0;
    }
    
    # check for balance
    if ($depth != 0) {
        say qq[Output: error - unbalanced parentheses];
        return;
    }
    
    # format output
    for $m (@decomp) {
        $m =~ m|^.(.*).$|;
        $output .= $1;
    }
    say qq[Output: '$output'];
    say qq[        Primitive decomposition = '] . 
        join(q[' + '], @decomp) . q['];
}

21 lines of code

Output from script


Input:  '()()()'
Output: ''
        Primitive decomposition = '()' + '()' + '()'

Input:  '(((())))'
Output: '((()))'
        Primitive decomposition = '(((())))'

Input:  '(()())(())'
Output: '()()()'
        Primitive decomposition = '(()())' + '(())'

Input:  '()((()))()'
Output: '(())'
        Primitive decomposition = '()' + '((()))' + '()'

Input:  '(()(()))(()())'
Output: '()(())()()'
        Primitive decomposition = '(()(()))' + '(()())'

Input:  '((())))'
Output: error - unbalanced parentheses

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain