Weekly Challenge 253
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.
Task 1: Split Strings
Task
You are given an array of strings and a character separator.
Write a script to return all words separated by the given character excluding empty string.
My solution
This is a little more straight forward in Python than Perl. In Python, I concatenate the words
with the sep
separator. I then split on the separator, excluding any empty words.
def split_strings(words, sep):
combined = sep.join(words)
return [ w for w in combined.split(sep) if w != '']
In Perl, the split function takes a regular expression. Therefore I need to add an extra step to escape any metacharacters that have special meaning.
sub split_strings ( $words, $sep ) {
my $combined = join( $sep, @$words );
if ( index( '{}[]()^$.|*+?\\', $sep ) != -1 ) {
$sep = "\\$sep";
}
my @result = grep { length($_) } split( /$sep/, $combined );
return \@result;
}
Examples
$ ./ch-1.py one.two.three four.five six .
"one", "two", "three", "four", "five", "six"
$ ./ch-1.py '$perl$$' '$$raku$' '$'
"perl", "raku"
Task 2: Weakest Row
Task
You are given an m x n binary matrix i.e. only 0
and 1
where 1
always appear before 0
.
A row i
is weaker than a row j
if one of the following is true:
- The number of
1
s in rowi
is less than the number of1
s in rowj
. - Both rows have the same number of
1
andi < j
.
My solution
For this task I take the input as a json string, which should be any array of arrays of ones and zeros. The first thing I do is call the validate_matrix
function, which does three checks:
- All rows have the same number of columns.
- All values are either
0
or1
- No
1
appears after a0
.
I then have a one liner to return the result.
def weakest_row(matrix):
validate_matrix(matrix)
return sorted(range(len(matrix)), key=lambda i: sum(matrix[i]))
Lets unpack that line
-
range(len(matrix))
simply returns a list from0
to one less than the length of array. -
sum(maxtrix[i]))
will calculate the number of1
s in the row. -
key=lambda i: ...
will sort by the number of 1s (lowest first). - In Python, sorting is stable. This means if two rows have the same sum, the original order is preserved.
The Perl solution follows the same logic, albeit with slightly different syntax. Using <=>
and ||
is well documented in the sort function.
my @sorted = sort {
sum( @{ $matrix->[$a] } ) <=> sum( @{ $matrix->[$b] } ) || $a <=> $b
} ( 0 .. $#$matrix );
Examples
$ ./ch-2.py "[ [1, 1, 0, 0, 0], [1, 1, 1, 1, 0], [1, 0, 0, 0, 0], [1, 1, 0, 0, 0], [1, 1, 1, 1, 1]]"
(2, 0, 3, 1, 4)
$ ./ch-2.py "[ [1, 0, 0, 0], [1, 1, 1, 1], [1, 0, 0, 0], [1, 0, 0, 0] ]"
(0, 2, 3, 1)
Top comments (0)