diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2024-04-14 11:35:58 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-14 11:35:58 +0100 |
| commit | 34f6677d42eedaf6001afe6f27da76127d02ba8e (patch) | |
| tree | 48813632543d480a939266f2cf068307e8471c00 | |
| parent | 2e7a3008d30320520aff3ebfa94c992ed0a29bad (diff) | |
| parent | 10c90091735911f345e5bd660b94f9982bba6c1d (diff) | |
| download | perlweeklychallenge-club-34f6677d42eedaf6001afe6f27da76127d02ba8e.tar.gz perlweeklychallenge-club-34f6677d42eedaf6001afe6f27da76127d02ba8e.tar.bz2 perlweeklychallenge-club-34f6677d42eedaf6001afe6f27da76127d02ba8e.zip | |
Merge pull request #9919 from PerlMonk-Athanasius/branch-for-challenge-264
Perl & Raku solutions to Tasks 1 & 2 for Week 264
| -rw-r--r-- | challenge-264/athanasius/perl/ch-1.pl | 172 | ||||
| -rw-r--r-- | challenge-264/athanasius/perl/ch-2.pl | 245 | ||||
| -rw-r--r-- | challenge-264/athanasius/raku/ch-1.raku | 159 | ||||
| -rw-r--r-- | challenge-264/athanasius/raku/ch-2.raku | 225 |
4 files changed, 801 insertions, 0 deletions
diff --git a/challenge-264/athanasius/perl/ch-1.pl b/challenge-264/athanasius/perl/ch-1.pl new file mode 100644 index 0000000000..bba7f30c47 --- /dev/null +++ b/challenge-264/athanasius/perl/ch-1.pl @@ -0,0 +1,172 @@ +#!perl + +################################################################################ +=comment + +Perl Weekly Challenge 264 +========================= + +TASK #1 +------- +*Greatest English Letter* + +Submitted by: Mohammad Sajid Anwar + +You are given a string, $str, made up of only alphabetic characters [a..zA..Z]. + +Write a script to return the greatest english letter in the given string. + + A letter is greatest if it occurs as lower and upper case. Also letter 'b' + is greater than 'a' if 'b' appears after 'a' in the English alphabet. + +Example 1 + + Input: $str = 'PeRlwEeKLy' + Output: L + + There are two letters E and L that appears as lower and upper. + The letter L appears after E, so the L is the greatest english letter. + +Example 2 + + Input: $str = 'ChaLlenge' + Output: L + +Example 3 + + Input: $str = 'The' + Output: '' + +=cut +################################################################################ + +#--------------------------------------# +# Copyright © 2024 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=comment + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. A single string, containing alphabetic characters only, is given on the + command-line. + +=cut +#=============================================================================== + +use v5.32.1; # Enables strictures +use warnings; +use Const::Fast; +use Test::More; + +const my $USAGE => <<END; +Usage: + perl $0 <str> + perl $0 + + <str> A string containing alphabetic characters (A-Z, a-z) only +END + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + $| = 1; + print "\nChallenge 264, Task #1: Greatest English Letter (Perl)\n\n"; +} + +#=============================================================================== +MAIN: +#=============================================================================== +{ + my $argc = scalar @ARGV; + + if ($argc == 0) + { + run_tests(); + } + elsif ($argc == 1) + { + my $str = $ARGV[ 0 ]; + + $str =~ / ^ [[:alpha:]]* $ /x + or error( qq[Invalid input string "$str"] ); + + print "Input: \$str = '$str'\n"; + + my $gel = find_greatest_English_letter( $str ); + + print "Output: '$gel'\n"; + } + else + { + error( qq[Expected 1 or 0 command-line arguments, found $argc] ); + } +} + +#------------------------------------------------------------------------------- +sub find_greatest_English_letter +#------------------------------------------------------------------------------- +{ + my ($str) = @_; + my %letters; + ++$letters{ $_ } for split //, $str; + + my $gel = ''; + my @uc = grep { / ^ [[:upper:]] $ /x } keys %letters; + + for (sort { $b cmp $a } @uc) # Sort descending + { + if (exists $letters{ lc() }) + { + $gel = $_; + last; + } + } + + return $gel; +} + +#------------------------------------------------------------------------------- +sub run_tests +#------------------------------------------------------------------------------- +{ + print "Running the test suite\n"; + + while (my $line = <DATA>) + { + chomp $line; + + my ($test_name, $str, $expected) = split / \| /x, $line; + + for ($test_name, $str, $expected) + { + s/ ^ \s+ //x; + s/ \s+ $ //x; + } + + my $gel = find_greatest_English_letter( $str ); + + is $gel, $expected, $test_name; + } + + done_testing; +} + +#------------------------------------------------------------------------------- +sub error +#------------------------------------------------------------------------------- +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +################################################################################ + +__DATA__ +Example 1|PeRlwEeKLy|L +Example 2|ChaLlenge |L +Example 3|The | diff --git a/challenge-264/athanasius/perl/ch-2.pl b/challenge-264/athanasius/perl/ch-2.pl new file mode 100644 index 0000000000..c6305143c6 --- /dev/null +++ b/challenge-264/athanasius/perl/ch-2.pl @@ -0,0 +1,245 @@ +#!perl + +################################################################################ +=comment + +Perl Weekly Challenge 264 +========================= + +TASK #2 +------- +*Target Array* + +Submitted by: Mohammad Sajid Anwar + +You are given two arrays of integers, @source and @indices. The @indices can +only contains integers 0 <= i < size of @source. + +Write a script to create target array by insert at index $indices[i] the value +$source[i]. + +Example 1 + + Input: @source = (0, 1, 2, 3, 4) + @indices = (0, 1, 2, 2, 1) + Output: (0, 4, 1, 3, 2) + + @source @indices @target + 0 0 (0) + 1 1 (0, 1) + 2 2 (0, 1, 2) + 3 2 (0, 1, 3, 2) + 4 1 (0, 4, 1, 3, 2) + +Example 2 + + Input: @source = (1, 2, 3, 4, 0) + @indices = (0, 1, 2, 3, 0) + Output: (0, 1, 2, 3, 4) + + @source @indices @target + 1 0 (1) + 2 1 (1, 2) + 3 2 (1, 2, 3) + 4 3 (1, 2, 3, 4) + 0 0 (0, 1, 2, 3, 4) + +Example 3 + + Input: @source = (1) + @indices = (0) + Output: (1) + +=cut +################################################################################ + +#--------------------------------------# +# Copyright © 2024 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=comment + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. The lists $source and $indices are entered as named-argument strings on the + command-line. + - Each is a list of integers separated by whitespace. + - $indices contains unsigned integers (i, j, k, ...) such that each is less + than or equal to its own index position in the list: i = 0, 0 <= j <= 1, + 0 <= k <= 2, etc. + +=cut +#=============================================================================== + +use v5.32.1; # Enables strictures +use warnings; +use Const::Fast; +use Getopt::Long; +use Regexp::Common qw( number ); +use Test::More; + +const my $USAGE => <<END; +Usage: + perl $0 [--source=<Str>] [--indices=<Str>] + perl $0 + + --source=<Str> A whitespace-separated list of integers + --indices=<Str> A whitespace-separated list of positive integers +END + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + $| = 1; + print "\nChallenge 264, Task #2: Target Array (Perl)\n\n"; +} + +#=============================================================================== +MAIN: +#=============================================================================== +{ + if (scalar @ARGV == 0) + { + run_tests(); + } + else + { + my ($source, $indices) = parse_command_line(); + + printf "Input: \@source = (%s)\n", join ', ', @$source; + printf " \@indices = (%s)\n", join ', ', @$indices; + + my $target = construct_target( $source, $indices ); + + printf "Output: \@target = (%s)\n", join ', ', @$target; + } +} + +#------------------------------------------------------------------------------- +sub construct_target +#------------------------------------------------------------------------------- +{ + my ($source, $indices) = @_; + my @target; + + for my $i (0 .. $#$source) + { + splice @target, $indices->[ $i ], 0, $source->[ $i ]; + } + + return \@target; +} + +#------------------------------------------------------------------------------- +sub parse_command_line +#------------------------------------------------------------------------------- +{ + my ($source_str, $indices_str); + + GetOptions + ( + 'source=s' => \$source_str, + 'indices2=s' => \$indices_str + + ) or error( 'Invalid command-line arguments' ); + + $source_str // error( 'Missing source' ); + $indices_str // error( 'Missing indices' ); + scalar @ARGV == 0 or error( 'Extra command-line arguments' ); + + my $source = parse_source ( $source_str ); + my $indices = parse_indices( $indices_str ); + + scalar @$source == scalar @$indices + or error( 'The input lists are of different sizes' ); + + return ($source, $indices); +} + +#------------------------------------------------------------------------------- +sub parse_source +#------------------------------------------------------------------------------- +{ + my ($source_str) = @_; + my @source; + + for my $s (split / \s+ /x, $source_str) + { + $s =~ / ^ $RE{num}{int} $ /x + or error( qq["$s" is not a valid integer] ); + + push @source, $s; + } + + return \@source; +} + +#------------------------------------------------------------------------------- +sub parse_indices +#------------------------------------------------------------------------------- +{ + my ($indices_str) = @_; + my $count = 0; + my @indices; + + for my $i (split / \s+ /x, $indices_str) + { + $i =~ / ^ $RE{num}{int} $ /x + or error( qq["$i" is not a valid integer] ); + $i >= 0 or error( qq["$i" is negative] ); + $i <= $count++ or error( qq[The index "$i" is too large] ); + + push @indices, $i; + } + + return \@indices; +} + +#------------------------------------------------------------------------------- +sub run_tests +#------------------------------------------------------------------------------- +{ + print "Running the test suite\n"; + + while (my $line = <DATA>) + { + chomp $line; + + my ($test_name, $source_str, $indices_str, $expected_str) = + split / \| /x, $line; + + for ($test_name, $source_str, $indices_str, $expected_str) + { + s/ ^ \s+ //x; + s/ \s+ $ //x; + } + + my @source = split / \s+ /x, $source_str; + my @indices = split / \s+ /x, $indices_str; + my @expected = split / \s+ /x, $expected_str; + my $target = construct_target( \@source, \@indices ); + + is_deeply $target, \@expected, $test_name; + } + + done_testing; +} + +#------------------------------------------------------------------------------- +sub error +#------------------------------------------------------------------------------- +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +################################################################################ + +__DATA__ +Example 1|0 1 2 3 4|0 1 2 2 1|0 4 1 3 2 +Example 2|1 2 3 4 0|0 1 2 3 0|0 1 2 3 4 +Example 3|1 |0 |1 diff --git a/challenge-264/athanasius/raku/ch-1.raku b/challenge-264/athanasius/raku/ch-1.raku new file mode 100644 index 0000000000..c466919ccc --- /dev/null +++ b/challenge-264/athanasius/raku/ch-1.raku @@ -0,0 +1,159 @@ +use v6d; + +################################################################################ +=begin comment + +Perl Weekly Challenge 264 +========================= + +TASK #1 +------- +*Greatest English Letter* + +Submitted by: Mohammad Sajid Anwar + +You are given a string, $str, made up of only alphabetic characters [a..zA..Z]. + +Write a script to return the greatest english letter in the given string. + + A letter is greatest if it occurs as lower and upper case. Also letter 'b' + is greater than 'a' if 'b' appears after 'a' in the English alphabet. + +Example 1 + + Input: $str = 'PeRlwEeKLy' + Output: L + + There are two letters E and L that appears as lower and upper. + The letter L appears after E, so the L is the greatest english letter. + +Example 2 + + Input: $str = 'ChaLlenge' + Output: L + +Example 3 + + Input: $str = 'The' + Output: '' + +=end comment +################################################################################ + +#--------------------------------------# +# Copyright © 2024 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=begin comment + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. A single string, containing alphabetic characters only, is given on the + command-line. + +=end comment +#=============================================================================== + +use Test; + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + "\nChallenge 264, Task #1: Greatest English Letter (Raku)\n".put; +} + +#=============================================================================== +multi sub MAIN +( + #| A string containing alphabetic characters (A-Z, a-z) only + + Str:D $str where / ^ <[ a .. z A .. Z ]>* $ /; +) +#=============================================================================== +{ + "Input: \$str = '$str'".put; + + my Str $gel = find-greatest-English-letter( $str ); + + "Output: '$gel'".put; +} + +#=============================================================================== +multi sub MAIN() # No input: run the test suite +#=============================================================================== +{ + run-tests(); +} + +#------------------------------------------------------------------------------- +sub find-greatest-English-letter( Str:D $str --> Str:D ) +#------------------------------------------------------------------------------- +{ + my UInt %letters; + ++%letters{ $_ } for $str.split: '', :skip-empty; + + my Str $gel = ''; + my Str @uc = %letters.keys.grep: { / ^ <.upper> $ / }; + + for @uc.sort.reverse + { + if %letters{ .lc }:exists + { + $gel = $_; + last; + } + } + + return $gel; +} + +#------------------------------------------------------------------------------- +sub run-tests() +#------------------------------------------------------------------------------- +{ + 'Running the test suite'.put; + + for test-data.lines -> Str $line + { + my Str ($test-name, $str, $expected) = $line.split: / \| /; + + for $test-name, $str, $expected + { + s/ ^ \s+ //; + s/ \s+ $ //; + } + + my Str $gel = find-greatest-English-letter( $str ); + + is $gel, $expected, $test-name; + } + + done-testing; +} + +#------------------------------------------------------------------------------- +sub USAGE() +#------------------------------------------------------------------------------- +{ + my Str $usage = $*USAGE; + + $usage ~~ s:g/ ($*PROGRAM-NAME) /raku $0/; + + $usage.put; +} + +#------------------------------------------------------------------------------- +sub test-data( --> Str:D ) +#------------------------------------------------------------------------------- +{ + return q:to/END/; + Example 1|PeRlwEeKLy|L + Example 2|ChaLlenge |L + Example 3|The | + END +} + +################################################################################ diff --git a/challenge-264/athanasius/raku/ch-2.raku b/challenge-264/athanasius/raku/ch-2.raku new file mode 100644 index 0000000000..ff3900c25f --- /dev/null +++ b/challenge-264/athanasius/raku/ch-2.raku @@ -0,0 +1,225 @@ +use v6d; + +################################################################################ +=begin comment + +Perl Weekly Challenge 264 +========================= + +TASK #2 +------- +*Target Array* + +Submitted by: Mohammad Sajid Anwar + +You are given two arrays of integers, @source and @indices. The @indices can +only contains integers 0 <= i < size of @source. + +Write a script to create target array by insert at index $indices[i] the value +$source[i]. + +Example 1 + + Input: @source = (0, 1, 2, 3, 4) + @indices = (0, 1, 2, 2, 1) + Output: (0, 4, 1, 3, 2) + + @source @indices @target + 0 0 (0) + 1 1 (0, 1) + 2 2 (0, 1, 2) + 3 2 (0, 1, 3, 2) + 4 1 (0, 4, 1, 3, 2) + +Example 2 + + Input: @source = (1, 2, 3, 4, 0) + @indices = (0, 1, 2, 3, 0) + Output: (0, 1, 2, 3, 4) + + @source @indices @target + 1 0 (1) + 2 1 (1, 2) + 3 2 (1, 2, 3) + 4 3 (1, 2, 3, 4) + 0 0 (0, 1, 2, 3, 4) + +Example 3 + + Input: @source = (1) + @indices = (0) + Output: (1) + +=end comment +################################################################################ + +#--------------------------------------# +# Copyright © 2024 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=begin comment + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. The lists $source and $indices are entered as named-argument strings on the + command-line. + - Each is a list of integers separated by whitespace. + - $indices contains unsigned integers (i, j, k, ...) such that each is less + than or equal to its own index position in the list: i = 0, 0 <= j <= 1, + 0 <= k <= 2, etc. + +=end comment +#=============================================================================== + +use Test; + +subset MainArgs of List where (Array[Int], Array[UInt]); + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + "\nChallenge 264, Task #2: Target Array (Raku)\n".put; +} + +#=============================================================================== +multi sub MAIN +( + Str:D :$source, #= A whitespace-separated list of integers + Str:D :$indices #= A whitespace-separated list of positive integers +) +#=============================================================================== +{ + my MainArgs $args = parse-command-line( $source, $indices ); + + "Input: \@source = (%s)\n".printf: $args[ 0 ].join: ', '; + " \@indices = (%s)\n".printf: $args[ 1 ].join: ', '; + + my Int @target = construct-target( $args ); + + "Output: \@target = (%s)\n".printf: @target.join: ', '; +} + +#=============================================================================== +multi sub MAIN() # No input: run the test suite +#=============================================================================== +{ + run-tests(); +} + +#------------------------------------------------------------------------------- +sub construct-target( MainArgs:D $args --> List:D[Int:D] ) +#------------------------------------------------------------------------------- +{ + my Int @target; + + for 0 .. $args[ 0 ].end -> UInt $i + { + @target.splice( $args[ 1; $i ], 0, $args[ 0; $i ] ); + } + + return @target; +} + +#------------------------------------------------------------------------------- +sub parse-command-line( Str:D $source, Str:D $indices --> MainArgs:D ) +#------------------------------------------------------------------------------- +{ + my Int @source; + + for $source.split( / \s+ /, :skip-empty ) -> Str $s + { + +$s ~~ Int or error( qq["$s" is not a valid integer] ); + + @source.push: +$s; + } + + my UInt @indices; + my UInt $count = 0; + + for $indices.split( / \s+ /, :skip-empty ) -> Str $i + { + +$i ~~ Int or error( qq["$i" is not a valid integer] ); + $i >= 0 or error( qq["$i" is negative] ); + $i <= $count++ or error( qq[The index "$i" is too large] ); + + @indices.push: +$i; + } + + @source.elems == @indices.elems + or error( 'The input lists are of different sizes' ); + + return @source, @indices; +} + +#------------------------------------------------------------------------------- +sub run-tests() +#------------------------------------------------------------------------------- +{ + 'Running the test suite'.put; + + for test-data.lines -> Str $line + { + my Str ($test-name, $source-str, $indices-str, $expected-str) = + $line.split: / \| /; + + for $test-name, $source-str, $indices-str, $expected-str + { + s/ ^ \s+ //; + s/ \s+ $ //; + } + + my Int @source = parse-list( $source-str ); + my UInt @indices = parse-list( $indices-str ); + my Int @expected = parse-list( $expected-str ); + my Int @target = construct-target( [ @source, @indices ] ); + + is-deeply @target, @expected, $test-name; + } + + done-testing; +} + +#------------------------------------------------------------------------------- +sub parse-list( Str:D $string --> List:D[Int:D] ) +#------------------------------------------------------------------------------- +{ + return $string.split( / \s+ /, :skip-empty ).map( { .Int } ).list; +} + +#------------------------------------------------------------------------------- +sub error( Str:D $message ) +#------------------------------------------------------------------------------- +{ + "ERROR: $message".put; + + USAGE(); + + exit 0; +} + +#------------------------------------------------------------------------------- +sub USAGE() +#------------------------------------------------------------------------------- +{ + my Str $usage = $*USAGE; + + $usage ~~ s:g/ ($*PROGRAM-NAME) /raku $0/; + + $usage.put; +} + +#------------------------------------------------------------------------------- +sub test-data( --> Str:D ) +#------------------------------------------------------------------------------- +{ + return q:to/END/; + Example 1|0 1 2 3 4|0 1 2 2 1|0 4 1 3 2 + Example 2|1 2 3 4 0|0 1 2 3 0|0 1 2 3 4 + Example 3|1 |0 |1 + END +} + +################################################################################ |
