Weekly Challenge 385
Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. Unless otherwise stated, Copilot (and other AI tools) have NOT been used to generate the solution. It's a great way for us all to practice some coding.
Task 1: Uncommon Words
Task
You are given two sentences.
Write a script to return list of all uncommon words, order is not important.
My solution
This is relatively straight forward. I start with a Counter called word_freq which is a special type of dictionary which is ideal for counting frequencies.
I take one or more sentences as input. I loop through each sentence, separate them by spaces and increment the word_freq counter. I then return all words that have a frequency of 1.
Since Python 3.6, dictionaries maintain their order. Therefore the words in the output will maintain their order from the supplied sentences.
from collections import Counter
def uncommon_word(*sentences: str) -> list:
word_freq = Counter()
for sentence in sentences:
word_freq.update(sentence.split())
return [word for word in word_freq if word_freq[word] == 1]
Perl does not maintain order of hashes. For the Perl solution, I sort the unique words alphabetically. This is an example of stacking sort, map (to quote strings) and grep (to filter duplicated words) in a single function.
sub main (@sentences) {
my %word_freq = ();
foreach my $sentence (@sentences) {
foreach my $word ( split /\s+/, $sentence ) {
$word_freq{$word}++;
}
}
say "("
. join( ", ",
sort map { qq{"$_"} } grep { $word_freq{$_} == 1 } keys %word_freq )
. ")";
}
Examples
$ ./ch-1.py "apple banana apple" "banana orange"
("orange")
$ ./ch-1.py "cat dog" "bird fish"
("cat", "dog", "bird", "fish")
$ ./ch-1.py "the quick brown fox" "the quick"
("brown", "fox")
$ ./ch-1.py "hello" "hello"
()
$ ./ch-1.py "blue blue red" "red green green yellow"
("yellow")
Task 2: Outermost Parentheses
Task
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.
My solution
For this task, I start by checking that the supplied string only contains open and closing parentheses.
def outermost_parentheses(input_string: str) -> str:
if not re.search(r"^[()]+$", input_string):
raise ValueError("Invalid input")
I then create two variables. output will store the string that is returned to the user, while open_count variable stores how many unclosed open parentheses there are.
output = ""
open_count = 0
The rest of the function loops through each character of input_string incrementing and decreasing the open_count value as needed. If open_count is 1 (after the increment, or before the decrement), then it is the opening or closing the outermost parentheses, and is not added to the output string.
I also have checks to ensure that a closing parentheses does not appear before the opening one, and all open parentheses are closed at the end of the string.
for char in input_string:
if char == "(":
open_count += 1
if open_count != 1:
output += char
if char == ")":
open_count -= 1
if open_count < 0:
raise ValueError("Too many closing parentheses")
if open_count != 0:
raise ValueError("Not enough closing parentheses")
return output
The Perl solution follows the same logic.
Examples
$ ./ch-2.py "()()()"
""
$ ./ch-2.py "(((())))"
"((()))"
$ ./ch-2.py "(()())(())"
"()()()"
$ ./ch-2.py "()((()))()"
"(())"
$ ./ch-2.py "(()(()))(()())"
"()(())()()"
Top comments (0)