aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2024-04-14 11:35:58 +0100
committerGitHub <noreply@github.com>2024-04-14 11:35:58 +0100
commit34f6677d42eedaf6001afe6f27da76127d02ba8e (patch)
tree48813632543d480a939266f2cf068307e8471c00
parent2e7a3008d30320520aff3ebfa94c992ed0a29bad (diff)
parent10c90091735911f345e5bd660b94f9982bba6c1d (diff)
downloadperlweeklychallenge-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.pl172
-rw-r--r--challenge-264/athanasius/perl/ch-2.pl245
-rw-r--r--challenge-264/athanasius/raku/ch-1.raku159
-rw-r--r--challenge-264/athanasius/raku/ch-2.raku225
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
+}
+
+################################################################################