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