DEV Community

Simon Green
Simon Green

Posted on

The weakest split

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.

Challenge, My solutions

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 != '']
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

Examples

$ ./ch-1.py one.two.three four.five six .
"one", "two", "three", "four", "five", "six"

$ ./ch-1.py '$perl$$' '$$raku$' '$'
"perl", "raku"
Enter fullscreen mode Exit fullscreen mode

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:

  1. The number of 1s in row i is less than the number of 1s in row j.
  2. Both rows have the same number of 1 and i < 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:

  1. All rows have the same number of columns.
  2. All values are either 0 or 1
  3. No 1 appears after a 0.

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]))
Enter fullscreen mode Exit fullscreen mode

Lets unpack that line

  1. range(len(matrix)) simply returns a list from 0 to one less than the length of array.
  2. sum(maxtrix[i])) will calculate the number of 1s in the row.
  3. key=lambda i: ... will sort by the number of 1s (lowest first).
  4. 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 );
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

Top comments (0)