Perl Weekly Challenge 266.

My solutions (task 1 and task 2 ) to the The Weekly Challenge - 266.

Task 1: Uncommon Words

Submitted by: Mohammad Sajid Anwar
You are given two sentences, $line1 and $line2.

Write a script to find all uncommmon words in any order in the given two sentences.
Return ('') if none found.

A word is uncommon if it appears exactly once in one of the sentences and doesn’t
appear in other sentence.

Example 1
Input: $line1 = 'Mango is sweet'
       $line2 = 'Mango is sour'
Output: ('sweet', 'sour')
Example 2
Input: $line1 = 'Mango Mango'
       $line2 = 'Orange'
Output: ('Orange')
Example 3
Input: $line1 = 'Mango is Mango'
       $line2 = 'Orange is Orange'
Output: ('')

I split all words of all phrases and count each with a hash. The results are those keys with a count of one. This yields a one-liner.

Example 1:

perl -E '
$w{lc $_}++ for split /\W+/, "@ARGV"; say "@ARGV -> ", join " ", (grep {$w{$_}==1} keys %w)
' "Mango is sweet" "mango is sour"

Results:

Mango is sweet mango is sour -> sour sweet

Example 2:

perl -E '
$w{lc $_}++ for split /\W+/, "@ARGV"; say "@ARGV -> ", join " ", grep {$w{$_}==1} keys %w
     ' "Mango mango" "Orange"

Results:

Mango mango Orange -> orange

Example 3:

perl -E '
$w{lc $_}++ for split /\W+/, "@ARGV"; say "@ARGV -> ", join " ", grep {$w{$_}==1} keys %w
     ' "Mango is Mango" "Orange is Orange"

Results:

Mango is Mango Orange is Orange ->

The full code adds some checks and formatting:

 1  # Perl weekly challenge 266
 2  # Task 1:  Uncommon Words
 3  #
 4  # See https://wlmb.github.io/2024/04/21/PWC266/#task-1-uncommon-words
 5  use v5.36;
 6  die <<~"FIN" unless @ARGV;
 7      Usage: $0 S1 [S2...]
 8      to find uncommon words in the strings S1, S2...
 9      FIN
10  my %count;
11  $count{lc $_}++ for split /\W+/, "@ARGV";
12  my @output=sort {$a cmp $b} grep {$count{$_}==1} keys %count;
13  push @output, "''" unless @output;
14  say join " ", map({"'".$_."'"} @ARGV), "->", @output;

Examples:

./ch-1.pl "Mango is sweet" "Mango is sour"
./ch-1.pl "Mango mango" "orange"
./ch-1.pl "Mango is Mango" "Orange is Orange"

Results:

'Mango is sweet' 'Mango is sour' -> sour sweet
'Mango mango' 'orange' -> orange
'Mango is Mango' 'Orange is Orange' -> ''

Task 2: X Matrix

Submitted by: Mohammad Sajid Anwar
You are given a square matrix, $matrix.

Write a script to find if the given matrix is X Matrix.

A square matrix is an X Matrix if all the elements on the main diagonal
and antidiagonal are non-zero and everything else are zero.

Example 1
Input: $matrix = [ [1, 0, 0, 2],
                   [0, 3, 4, 0],
                   [0, 5, 6, 0],
                   [7, 0, 0, 1],
                 ]
Output: true
Example 2
Input: $matrix = [ [1, 2, 3],
                   [4, 5, 6],
                   [7, 8, 9],
                 ]
Output: false
Example 3
Input: $matrix = [ [1, 0, 2],
                   [0, 3, 0],
                   [4, 0, 5],
                 ]
Output: true

I use the Perl Data Language PDL to manipulate matrices. I build an X shaped matric with 1’s on the diagonals and 0 outside. The result is true if the logical values of all of the entries of the given matrix are equal to those of the X shaped matrix. The result fits a 1.5-liner.

Example 1:

perl -MPDL -MPDL::NiceSlice -E '
$m=pdl shift;$x=($m->xvals==$m->yvals)|$m->xvals->(-1:0)==$m->yvals;
say "$m -> ", (!!$m==$x)->all?"True":"False";
' "[[1 0 0 2][0 3 4 0][0 5 6 0][7 0 0 1]]"

Results:

[
 [1 0 0 2]
 [0 3 4 0]
 [0 5 6 0]
 [7 0 0 1]
]
 -> True

Example 2:

perl -MPDL -MPDL::NiceSlice -E '
$m=pdl shift;$x=($m->xvals==$m->yvals)|$m->xvals->(-1:0)==$m->yvals;
say "$m -> ", (!!$m==$x)->all?"True":"False";
' "[[1 2 3][4 5 6][7 8 9]]"

Results:

[
 [1 2 3]
 [4 5 6]
 [7 8 9]
]
 -> False

Example 3:

perl -MPDL -MPDL::NiceSlice -E '
$m=pdl shift;$x=($m->xvals==$m->yvals)|$m->xvals->(-1:0)==$m->yvals;
say "$m -> ", (!!$m==$x)->all?"True":"False";
' "[[1 0 2][0 3 0][4 0 5]]"

Results:

[
 [1 0 2]
 [0 3 0]
 [4 0 5]
]
 -> True

The full code is similar.

 1  # Perl weekly challenge 266
 2  # Task 2:  X Matrix
 3  #
 4  # See https://wlmb.github.io/2024/04/21/PWC266/#task-2-x-matrix
 5  use v5.36;
 6  use PDL;
 7  use PDL::NiceSlice;
 8  die <<~"FIN" unless @ARGV;
 9      Usage: $0 M1 [M2...]
10      to find out if the matrices M1, M2... are X shaped.
11      Each matrix should be of the form "[[M11 M12...][M21 M22...]...]"
12      where Mij are the matrix elements. Separating commas are optional.
13      FIN
14  for(@ARGV){
15      my $matrix=pdl $_;
16      my $x=($matrix->xvals==$matrix->yvals) | ($matrix->xvals->(-1:0)==$matrix->yvals);
17      my $output=(!!$matrix == $x)->all?"True":"False";
18      say "$matrix -> $output";
19  }

Examples:

./ch-2.pl "[[1 0 0 2][0 3 4 0][0 5 6 0][7 0 0 1]]"\
	  "[[1 2 3][4 5 6][7 8 9]]"\
	  "[[1 0 2][0 3 0][4 0 5]]"

Results:

[
 [1 0 0 2]
 [0 3 4 0]
 [0 5 6 0]
 [7 0 0 1]
]
 -> True

[
 [1 2 3]
 [4 5 6]
 [7 8 9]
]
 -> False

[
 [1 0 2]
 [0 3 0]
 [4 0 5]
]
 -> True
Written on April 21, 2024