DEV Community

Simon Green
Simon Green

Posted on

The one about regular expressions

Weekly Challenge 239

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. It's a great way for us all to practice some coding.

Challenge, My solutions

Task 1: Same String

Task

You are given two arrays of strings.

Write a script to find out if the word created by concatenating the array elements is the same.

My solution

Both of this weeks solutions involve regular expressions, but this one is definitely a hack. But that is what regex is for, isn't it? :)

Sometimes the challenge in these tasks is how to parse the input. Most of the items it's just a list, and we can retrieve that for sys.argv (@ARGV in Perl). When it's two lists, it's a bit harder. We could accept a JSON list, but that is a little overkill for this.

For this task, I take two inputs from the command line. I then strip everything that isn't a letter, and then compare the values. This allows the inputs to be a list, space separate or whatever format the user chooses.

if re.sub('[^a-z]', '', lists[0], flags=re.IGNORECASE) == \
        re.sub('[^a-z]', '', lists[1], flags=re.IGNORECASE):
    print('true')
else:
    print('false')
Enter fullscreen mode Exit fullscreen mode

The Perl code runs the regular expression s/[^a-z]//gi on each value and compares the resulting string.

Examples

$ ./ch-1.py '("ab", "c")' '("a", "bc")'
true

$ ./ch-1.py '("ab", "c")' '("ac", "b")'
false

$ ./ch-1.py '("ab", "cd", "e")' '("abcde")'
true
Enter fullscreen mode Exit fullscreen mode

Task 2: Consistent Strings

Task

You are given an array of strings and allowed string having distinct characters.

A string is consistent if all characters in the string appear in the string allowed.

Write a script to return the number of consistent strings in the given array.

My solution

This one of those times that the Python and Perl solution are different. The Perl solution would have worked in Python. As I write the Python code first, I stuck with the code that I originally wrote.

For the Python solution, I turn the string into a regular expression - escaping special characters. Then I count the words that match the regular expression.

r = f'^[{re.escape(allowed)}]+$'
count = sum(1 for word in words if re.search(r, word))
Enter fullscreen mode Exit fullscreen mode

Perl doesn't have a built-in escape function. This means if the allowed characters were a, - and z, it would be interpreted as the 26 letters of the alphabet, rather than the three characters. And I definitely don't feel like writing my own escape function.

For the Perl solution, I created a hash called allowed that contains each character of the allowed word. I then iterate over the word list, and check that all letters are in the allowed hash.

my %allowed = map { $_, 1 } split(//, $allowed);

foreach my $word (@words) {
    $count++ if all { exists $allowed{$_} } split(//, $word);
}
Enter fullscreen mode Exit fullscreen mode

Examples

$ ./ch-2.py ad bd aaab baa badab ab
2

$ ./ch-2.py a b c ab ac bc abc abc
7

$ ./ch-2.py cc acd b ba bac bad ac d cad
4
Enter fullscreen mode Exit fullscreen mode

Top comments (0)