Outermost Uncommon
with Raku

by Arne Sommer

Outermost Uncommon with Raku

[410] Published 7. August 2026.

This is my response to The Weekly Challenge #385.

#385.1 Uncommon Words You are given two sentences.

Write a script to return list of all uncommon words, order is not important.

Example 1:
Input: $sentence1 = "apple banana apple"
       $sentence2 = "banana orange"
Output: ("orange")
Example 2:
Input: $sentence1 = "cat dog"
       $sentence2 = "bird fish"
Output: ("cat", "dog", "bird", "fish")
Example 3:
Input: $sentence1 = "the quick brown fox"
       $sentence2 = "the quick"
Output: ("brown", "fox")
Example 4:
Input: $sentence1 = "hello"
       $sentence2 = "hello"
Output: ()
Example 5:
Input: $sentence1 = "blue blue red"
       $sentence2 = "red green green yellow"
Output: ("yellow")
File: uncommon-words
#! /usr/bin/env raku

unit sub MAIN (*@args);

(@args[0].words, @args[1].words)
  .Bag
  .grep({ .value == 1 })
  .map(*.key)
  .sort
  .say;

[3] Catch the arguments, whatever they may be.

I have sprinkled the original row 5 with a massive dose of newlines to make it easier to comment on each part.

[5] Split the first two arguments into words.

See docs.raku.org/routine/words for more information about words.

[6] Turn the two word lists into a Bag, a hash like structure with a key count.

See docs.raku.org/type/Bag for more information about the Bag type.

[7] Keep words that only occur once.

[8] Use map to extract the key - the word - from the Pair objects in the Bag.

[9] Sort the result,

[10] and print it.

Running it:

$ ./uncommon-words "apple banana apple" "banana orange"
(orange)

$ ./uncommon-words "cat dog" "bird fish"
(bird cat dog fish)

$ ./uncommon-words "the quick brown fox" "the quick"
(brown fox)

$ ./uncommon-words "hello" "hello"
()

$ ./uncommon-words "blue blue red" "red green green yellow"
(yellow)

Looking good.

No verbose mode on this one, as the onelinery format does not really accomodate it.

#385.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.

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: "(()(()))" + "(()())"
File: outermost-parenthesis
#! /usr/bin/env raku

unit sub MAIN ($str where $str ~~ /^ <[\(\)]>+ $/,
               :v($verbose));

my @primitives = gather
{
  my $depth     = 0;
  my $primitive = '';

  for $str.comb -> $char {
    $primitive ~= $char;
    $char eq '(' ?? $depth++ !! $depth--;

    die "Encountered ')' without a preciding '('" if $depth < 0;
    
    if $depth == 0
    {
      take $primitive;
      say ": Primitive: $primitive" if $verbose;
      $primitive = '';
    }
  }

  die "Missing ')'" if $depth > 0;
};

say @primitives.map({ .substr(1, .chars - 2) }).join;

[3] Ensure parenthesises only.

[6] Use gather/take to extract the primitive strings.

See my Raku Gather, I Take article or docs.raku.org/language/control#gather/take for more information about gather/take.

[8] The depth, or parenthesis count.

[9] The current primitive string is a work in progress.

[11] Iterate over the characters in the input.

[12] Add it to the primitive string.

[13] Update the depth.

[15] Negative dept? That's an error.

[17] Zero depth? Then we have a primitive string.

[19] Return it (with take).

[21] Reset the primitive string, ready for the next iteration - if any.

[25] Positive dept when finished (with the input) is an error.

[28] Get rid of the first and last character (i.e. the outermost parentheses) in each string, before printinh them.

Running it:

$ ./ outermost-parentheses "()()()"


$ ./outermost-parentheses "(((())))"
((()))

$ ./outermost-parentheses "(()())(())"
()()()

$ ./outermost-parentheses "()((()))()"
(())

$ ./outermost-parentheses "(()(()))(()())"
()(())()()

Looking good.

With verbose mode:

$ ./outermost-parentheses -v "()()()"
: Primitive: ()
: Primitive: ()
: Primitive: ()


$ ./outermost-parentheses -v "(((())))"
: Primitive: (((())))
((()))

$ ./outermost-parentheses -v "(()())(())"
: Primitive: (()())
: Primitive: (())
()()()

$ ./outermost-parentheses -v "()((()))()"
: Primitive: ()
: Primitive: ((()))
: Primitive: ()
(())

$ ./outermost-parentheses -v "(()(()))(()())"
: Primitive: (()(()))
: Primitive: (()())
()(())()()

And that's it.