From 5e1fbbf92cc4db6a38548ea86a09a5d84f57a4a5 Mon Sep 17 00:00:00 2001 From: Matthias Muth Date: Tue, 13 Feb 2024 16:46:21 +0100 Subject: Challenge 256 Task 1 and 2 solutions in Perl by Matthias Muth --- challenge-256/matthias-muth/README.md | 130 ++++++++++++++++++++- challenge-256/matthias-muth/blog.txt | 1 + challenge-256/matthias-muth/perl/ch-1.pl | 30 +++++ challenge-256/matthias-muth/perl/ch-2.pl | 28 +++++ challenge-256/matthias-muth/perl/challenge-256.txt | 49 ++++++++ 5 files changed, 234 insertions(+), 4 deletions(-) create mode 100644 challenge-256/matthias-muth/blog.txt create mode 100755 challenge-256/matthias-muth/perl/ch-1.pl create mode 100755 challenge-256/matthias-muth/perl/ch-2.pl create mode 100644 challenge-256/matthias-muth/perl/challenge-256.txt diff --git a/challenge-256/matthias-muth/README.md b/challenge-256/matthias-muth/README.md index 970c56c8bd..e483f78d49 100644 --- a/challenge-256/matthias-muth/README.md +++ b/challenge-256/matthias-muth/README.md @@ -1,5 +1,127 @@ -**Challenge 244 solutions in Perl by Matthias Muth** -
-(no blog post this time...) +# Challenge 256 tasks: Easy Pairs - Easy Merge +**Challenge 256 solutions in Perl by Matthias Muth** + +## Task 1: Maximum Pairs + +> You are given an array of distinct words, `@words`.
+> Write a script to find the maximum pairs in the given array. The words `$words[i]` and `$words[j]` can be a pair one is reverse of the other.
+>
+> Example 1
+> Input: @words = ("ab", "de", "ed", "bc")
+> Output: 1
+> There is one pair in the given array: "de" and "ed"
+>
+> Example 2
+> Input: @words = ("aa", "ba", "cd", "ed")
+> Output: 0
+>
+> Example 3
+> Input: @words = ("uv", "qp", "st", "vu", "mn", "pq"))
+> Output: 2
+ +Ah, an easy one.
+For each word we check whether we have seen its reverse before, and increment +our counter if so. Then we remember that we have seen the current word. + +Perl supports us with the `reverse` function to reverse the characters of a string (also to reverse a list, but this is not what we use here). + +```perl +#!/usr/bin/env perl +use v5.36; + +sub maximum_pairs( @words ) { + my $n = 0; + my %known; + for ( @words ) { + ++$n if $known{ reverse $_ }; + $known{$_} = 1; + } + return $n; +} + +use Test2::V0 qw( -no_srand ); +is maximum_pairs( "ab", "de", "ed", "bc" ), 1, + 'Example 1: maximum_pairs( ("ab", "de", "ed", "bc") ) == 1'; +is maximum_pairs( "aa", "ba", "cd", "ed" ), 0, + 'Example 2: maximum_pairs( ("aa", "ba", "cd", "ed") ) == 0'; +is maximum_pairs( "uv", "qp", "st", "vu", "mn", "pq" ), 2, + 'Example 3: maximum_pairs( ("uv", "qp", "st", "vu", "mn", "pq") ) == 2'; +done_testing; +``` + +If you don't have perl 5.36 (which I highly recommend!), you can use this +instead: + +```perl +use v5.20; +use warnings; +use feature 'signatures'; +no warnings 'experimental::signatures'; +``` +Perl 5.20 has been around since 2014, so I guess that chances are high +that your perl is more recent than that.
+If not, and you are not able to update your system's perl for any reason, +I suggest installing [`perlbrew`](https://perlbrew.pl), +which is an admin-free perl installation management tool. + +## Task 2: Merge Strings + +> You are given two strings, `$str1` and `$str2`.
+> Write a script to merge the given strings by adding in alternative order starting with the first string. If a string is longer than the other then append the remaining at the end.
+>
+> Example 1
+> Input: \$str1 = "abcd", \$str2 = "1234"
+> Output: "a1b2c3d4"
+>
+> Example 2
+> Input: \$str1 = "abc", \$str2 = "12345"
+> Output: "a1b2c345"
+>
+> Example 3
+> Input: \$str1 = "abcde", \$str2 = "123"
+> Output: "a1b2c3de"
+ +The idea for this challenge is to turn the two string into lists of characters, +and then merge the two lists.
+There are a lot of functions for list manipulations in the `List::Util` core +module, one of which is `mesh`. It does exactly what we need. +The only downside is that if the lists are of different lengths, there will be +`undef` values inserted in the result. But it is easy to `grep` those out +before assembling the result into a return string. +At least easier than splitting up the longer list into two parts, and after +`mesh`ing the first part with the shorter string appending the second part. + +`mesh` has been part of `List::Util` since its version 1.56, +which means has been part of standard Perl since Perl 5.25 (released in 2014). + +Its implementation is different from the `mesh` function in the +`List::MoreUtils` CPAN module, in that it uses array references as parameters, not array variables that are used *by reference* (using prototypes).
+I prefer the `List::Util` version here, +because we can directly use anonymous arrays containing the split characters as parameters, +making it unnecessary to declare and use any array variables. + +```perl +#!/usr/bin/env perl + +use v5.36; + +use List::Util qw( mesh ); + +sub merge_strings( $str1, $str2 ) { + return join "", + grep defined, + mesh [ split //, $str1 ], [ split //, $str2 ]; +} + +use Test2::V0 qw( -no_srand ); +is merge_strings( "abcd", 1234 ), "a1b2c3d4", + 'Example 1: merge_strings( ("abcd", 1234) ) == "a1b2c3d4"'; +is merge_strings( "abc", 12345 ), "a1b2c345", + 'Example 2: merge_strings( ("abc", 12345) ) == "a1b2c345"'; +is merge_strings( "abcde", 123 ), "a1b2c3de", + 'Example 3: merge_strings( ("abcde", 123) ) == "a1b2c3de"'; +done_testing; +``` + +#### **Thank you for the challenge!** -**Thank you for the challenge!** diff --git a/challenge-256/matthias-muth/blog.txt b/challenge-256/matthias-muth/blog.txt new file mode 100644 index 0000000000..ee2ca51766 --- /dev/null +++ b/challenge-256/matthias-muth/blog.txt @@ -0,0 +1 @@ +https://github.com/MatthiasMuth/perlweeklychallenge-club/tree/muthm-256/challenge-256/matthias-muth#readme diff --git a/challenge-256/matthias-muth/perl/ch-1.pl b/challenge-256/matthias-muth/perl/ch-1.pl new file mode 100755 index 0000000000..88d640eb2d --- /dev/null +++ b/challenge-256/matthias-muth/perl/ch-1.pl @@ -0,0 +1,30 @@ +#!/usr/bin/env perl +# +# The Weekly Challenge - Perl & Raku +# (https://theweeklychallenge.org) +# +# Challenge 256 Task 1: Maximum Pairs +# +# Perl solution by Matthias Muth. +# + +use v5.36; + +sub maximum_pairs( @words ) { + my $n = 0; + my %known; + for ( @words ) { + ++$n if $known{ reverse $_ }; + $known{$_} = 1; + } + return $n; +} + +use Test2::V0 qw( -no_srand ); +is maximum_pairs( "ab", "de", "ed", "bc" ), 1, + 'Example 1: maximum_pairs( ("ab", "de", "ed", "bc") ) == 1'; +is maximum_pairs( "aa", "ba", "cd", "ed" ), 0, + 'Example 2: maximum_pairs( ("aa", "ba", "cd", "ed") ) == 0'; +is maximum_pairs( "uv", "qp", "st", "vu", "mn", "pq" ), 2, + 'Example 3: maximum_pairs( ("uv", "qp", "st", "vu", "mn", "pq") ) == 2'; +done_testing; diff --git a/challenge-256/matthias-muth/perl/ch-2.pl b/challenge-256/matthias-muth/perl/ch-2.pl new file mode 100755 index 0000000000..701aff3283 --- /dev/null +++ b/challenge-256/matthias-muth/perl/ch-2.pl @@ -0,0 +1,28 @@ +#!/usr/bin/env perl +# +# The Weekly Challenge - Perl & Raku +# (https://theweeklychallenge.org) +# +# Challenge 256 Task 2: Merge Strings +# +# Perl solution by Matthias Muth. +# + +use v5.36; + +use List::Util qw( mesh ); + +sub merge_strings( $str1, $str2 ) { + return join "", + grep defined, + mesh [ split //, $str1 ], [ split //, $str2 ]; +} + +use Test2::V0 qw( -no_srand ); +is merge_strings( "abcd", 1234 ), "a1b2c3d4", + 'Example 1: merge_strings( ("abcd", 1234) ) == "a1b2c3d4"'; +is merge_strings( "abc", 12345 ), "a1b2c345", + 'Example 2: merge_strings( ("abc", 12345) ) == "a1b2c345"'; +is merge_strings( "abcde", 123 ), "a1b2c3de", + 'Example 3: merge_strings( ("abcde", 123) ) == "a1b2c3de"'; +done_testing; diff --git a/challenge-256/matthias-muth/perl/challenge-256.txt b/challenge-256/matthias-muth/perl/challenge-256.txt new file mode 100644 index 0000000000..2c68ed9512 --- /dev/null +++ b/challenge-256/matthias-muth/perl/challenge-256.txt @@ -0,0 +1,49 @@ +The Weekly Challenge - 256 +Monday, Feb 12, 2024 + + +Task 1: Maximum Pairs +Submitted by: Mohammad Sajid Anwar + +You are given an array of distinct words, @words. +Write a script to find the maximum pairs in the given array. The words $words[i] and $words[j] can be a pair one is reverse of the other. +Example 1 + +Input: @words = ("ab", "de", "ed", "bc") +Output: 1 + +There is one pair in the given array: "de" and "ed" + +Example 2 + +Input: @words = ("aa", "ba", "cd", "ed") +Output: 0 + +Example 3 + +Input: @words = ("uv", "qp", "st", "vu", "mn", "pq") +Output: 2 + + +Task 2: Merge Strings +Submitted by: Mohammad Sajid Anwar + +You are given two strings, $str1 and $str2. +Write a script to merge the given strings by adding in alternative order starting with the first string. If a string is longer than the other then append the remaining at the end. +Example 1 + +Input: $str1 = "abcd", $str2 = "1234" +Output: "a1b2c3d4" + +Example 2 + +Input: $str1 = "abc", $str2 = "12345" +Output: "a1b2c345" + +Example 3 + +Input: $str1 = "abcde", $str2 = "123" +Output: "a1b2c3de" + + +Last date to submit the solution 23:59 (UK Time) Sunday 18th February 2024. -- cgit