aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2025-02-01 20:18:27 +0000
committerGitHub <noreply@github.com>2025-02-01 20:18:27 +0000
commit3bbbc72f866d8f71226fe112aeb53c20a1cb12e3 (patch)
treed23dbe55eebc1641a9573c4551117d0d75f8b634
parentbd20e3321fa66adb7e5734015c3cb71c22a38fc8 (diff)
parent69fc8fc4bb11fe89b98c90d11c416a6342cdb179 (diff)
downloadperlweeklychallenge-club-3bbbc72f866d8f71226fe112aeb53c20a1cb12e3.tar.gz
perlweeklychallenge-club-3bbbc72f866d8f71226fe112aeb53c20a1cb12e3.tar.bz2
perlweeklychallenge-club-3bbbc72f866d8f71226fe112aeb53c20a1cb12e3.zip
Merge pull request #11513 from PerlMonk-Athanasius/branch-for-challenge-306
Perl & Raku solutions to Tasks 1 & 2 for Week 306
-rw-r--r--challenge-306/athanasius/perl/ch-1.pl175
-rw-r--r--challenge-306/athanasius/perl/ch-2.pl178
-rw-r--r--challenge-306/athanasius/raku/ch-1.raku166
-rw-r--r--challenge-306/athanasius/raku/ch-2.raku170
4 files changed, 689 insertions, 0 deletions
diff --git a/challenge-306/athanasius/perl/ch-1.pl b/challenge-306/athanasius/perl/ch-1.pl
new file mode 100644
index 0000000000..df583412d8
--- /dev/null
+++ b/challenge-306/athanasius/perl/ch-1.pl
@@ -0,0 +1,175 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 306
+=========================
+
+TASK #1
+-------
+*Odd Sum*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of positive integers, @ints.
+
+Write a script to return the sum of all possible odd-length subarrays of the
+given array. A subarray is a contiguous subsequence of the array.
+
+Example 1
+
+ Input: @ints = (2, 5, 3, 6, 4)
+ Output: 77
+
+ Odd length sub-arrays:
+ (2) => 2
+ (5) => 5
+ (3) => 3
+ (6) => 6
+ (4) => 4
+ (2, 5, 3) => 10
+ (5, 3, 6) => 14
+ (3, 6, 4) => 13
+ (2, 5, 3, 6, 4) => 20
+
+ Sum => 2 + 5 + 3 + 6 + 4 + 10 + 14 + 13 + 20 => 77
+
+Example 2
+
+ Input: @ints = (1, 3)
+ Output: 4
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2025 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=comment
+
+Assumption
+----------
+A "positive" integer is greater than zero.
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. One or more positive integers are entered on the command-line.
+
+=cut
+#===============================================================================
+
+use v5.32; # Enables strictures
+use warnings;
+use Const::Fast;
+use Regexp::Common qw( number );
+use Test::More;
+
+const my $USAGE => <<END;
+Usage:
+ perl $0 [<ints> ...]
+ perl $0
+
+ [<ints> ...] A non-empty list of positive integers
+END
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 306, Task #1: Odd Sum (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ if (scalar @ARGV == 0)
+ {
+ run_tests();
+ }
+ else
+ {
+ my @ints = @ARGV;
+
+ for (@ints)
+ {
+ / ^ $RE{num}{int} $ /x or error( qq["$_" is not a valid integer] );
+ $_ > 0 or error( "$_ is not positive");
+ }
+
+ printf "Input: \@ints = (%s)\n", join ', ', @ints;
+
+ my $odd_sum = find_odd_sum( \@ints );
+
+ print "Output: $odd_sum\n";
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub find_odd_sum
+#-------------------------------------------------------------------------------
+{
+ my ($ints) = @_;
+ my $odd_sum = 0;
+
+ for my $i (0 .. $#$ints)
+ {
+ my $sum = 0;
+ my $count = 0;
+
+ for my $j ($i .. $#$ints)
+ {
+ $sum += $ints->[ $j ];
+ $odd_sum += $sum if ++$count % 2;
+ }
+ }
+
+ return $odd_sum;
+}
+
+#-------------------------------------------------------------------------------
+sub run_tests
+#-------------------------------------------------------------------------------
+{
+ print "Running the test suite\n";
+
+ while (my $line = <DATA>)
+ {
+ chomp $line;
+
+ my ($test_name, $ints_str, $expected) = split / \| /x, $line;
+
+ for ($test_name, $ints_str, $expected)
+ {
+ s/ ^ \s+ //x;
+ s/ \s+ $ //x;
+ }
+
+ my @ints = split / \s+ /x, $ints_str;
+ my $odd_sum = find_odd_sum( \@ints );
+
+ is $odd_sum, $expected, $test_name;
+ }
+
+ done_testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+################################################################################
+
+__DATA__
+Example 1|2 5 3 6 4|77
+Example 2|1 3 | 4
diff --git a/challenge-306/athanasius/perl/ch-2.pl b/challenge-306/athanasius/perl/ch-2.pl
new file mode 100644
index 0000000000..e718e40dfd
--- /dev/null
+++ b/challenge-306/athanasius/perl/ch-2.pl
@@ -0,0 +1,178 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 306
+=========================
+
+TASK #2
+-------
+*Last Element*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given a array of integers, @ints.
+
+Write a script to play a game where you pick two biggest integers in the given
+array, say x and y. Then do the following:
+
+ a) if x == y then remove both from the given array
+ b) if x != y then remove x and replace y with (y - x)
+
+At the end of the game, there is at most one element left.
+
+Return the last element if found otherwise return 0.
+
+Example 1
+
+ Input: @ints = (3, 8, 5, 2, 9, 2)
+ Output: 1
+
+ Step 1: pick 8 and 9 => (3, 5, 2, 1, 2)
+ Step 2: pick 3 and 5 => (2, 2, 1, 2)
+ Step 3: pick 2 and 1 => (1, 2, 2)
+ Step 4: pick 2 and 1 => (1, 2)
+ Step 5: pick 1 and 2 => (1)
+
+Example 2
+
+ Input: @ints = (3, 2, 5)
+ Output: 0
+
+ Step 1: pick 3 and 5 => (2, 2)
+ Step 2: pick 2 and 2 => ()
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2025 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=comment
+
+Assumption
+----------
+The input integers are positive (greater than zero).
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. One or more positive integers are entered on the command-line.
+
+=cut
+#===============================================================================
+
+use v5.32; # Enables strictures and warnings
+use Const::Fast;
+use Regexp::Common qw( number );
+use Test::More;
+
+const my $USAGE => <<END;
+Usage:
+ perl $0 [<ints> ...]
+ perl $0
+
+ [<ints> ...] A non-empty list of positive integers
+END
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 306, Task #2: Last Element (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ if (scalar @ARGV == 0)
+ {
+ run_tests();
+ }
+ else
+ {
+ my @ints = @ARGV;
+
+ for (@ints)
+ {
+ / ^ $RE{num}{int} $ /x or error( qq["$_" is not a valid integer] );
+ $_ > 0 or error( "$_ is not positive");
+ }
+
+ printf "Input: \@ints = (%s)\n", join ', ', @ints;
+
+ my $last_element = find_last_element( \@ints );
+
+ print "Output: $last_element\n";
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub find_last_element
+#-------------------------------------------------------------------------------
+{
+ my ($ints) = @_;
+ my @n = sort { $a <=> $b } @$ints;
+
+ while (scalar @n > 1)
+ {
+ my $y = pop @n;
+ my $x = pop @n;
+
+ if ($y > $x)
+ {
+ push @n, $y - $x;
+
+ @n = sort { $a <=> $b } @n;
+ }
+ }
+
+ return (scalar @n == 0) ? 0 : $n[ 0 ];
+}
+
+#-------------------------------------------------------------------------------
+sub run_tests
+#-------------------------------------------------------------------------------
+{
+ print "Running the test suite\n";
+
+ while (my $line = <DATA>)
+ {
+ chomp $line;
+
+ my ($test_name, $ints_str, $expected) = split / \| /x, $line;
+
+ for ($test_name, $ints_str, $expected)
+ {
+ s/ ^ \s+ //x;
+ s/ \s+ $ //x;
+ }
+
+ my @ints = split / \s+ /x, $ints_str;
+ my $last = find_last_element( \@ints );
+
+ is $last, $expected, $test_name;
+ }
+
+ done_testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+################################################################################
+
+__DATA__
+Example 1|3 8 5 2 9 2|1
+Example 2|3 2 5 |0
diff --git a/challenge-306/athanasius/raku/ch-1.raku b/challenge-306/athanasius/raku/ch-1.raku
new file mode 100644
index 0000000000..7f901f8a0f
--- /dev/null
+++ b/challenge-306/athanasius/raku/ch-1.raku
@@ -0,0 +1,166 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 306
+=========================
+
+TASK #1
+-------
+*Odd Sum*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of positive integers, @ints.
+
+Write a script to return the sum of all possible odd-length subarrays of the
+given array. A subarray is a contiguous subsequence of the array.
+
+Example 1
+
+ Input: @ints = (2, 5, 3, 6, 4)
+ Output: 77
+
+ Odd length sub-arrays:
+ (2) => 2
+ (5) => 5
+ (3) => 3
+ (6) => 6
+ (4) => 4
+ (2, 5, 3) => 10
+ (5, 3, 6) => 14
+ (3, 6, 4) => 13
+ (2, 5, 3, 6, 4) => 20
+
+ Sum => 2 + 5 + 3 + 6 + 4 + 10 + 14 + 13 + 20 => 77
+
+Example 2
+
+ Input: @ints = (1, 3)
+ Output: 4
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2025 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=begin comment
+
+Assumption
+----------
+A "positive" integer is greater than zero.
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. One or more positive integers are entered on the command-line.
+
+=end comment
+#===============================================================================
+
+use Test;
+
+subset Pos of Int where * > 0;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 306, Task #1: Odd Sum (Raku)\n".put;
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ #| A non-empty list of positive integers
+
+ *@ints where { .elems > 0 && .all ~~ Pos:D }
+)
+#===============================================================================
+{
+ "Input: \@ints = (%s)\n".printf: @ints.join: ', ';
+
+ my UInt $odd-sum = find-odd-sum( @ints );
+
+ "Output: $odd-sum".put;
+}
+
+#===============================================================================
+multi sub MAIN() # No input: run the test suite
+#===============================================================================
+{
+ run-tests();
+}
+
+#-------------------------------------------------------------------------------
+sub find-odd-sum( List:D[Pos:D] $ints --> UInt:D )
+#-------------------------------------------------------------------------------
+{
+ my $odd-sum = 0;
+
+ for 0 .. $ints.end -> UInt $i
+ {
+ my UInt $sum = 0;
+ my UInt $count = 0;
+
+ for $i .. $ints.end -> UInt $j
+ {
+ $sum += $ints[ $j ];
+ $odd-sum += $sum if ++$count % 2;
+ }
+ }
+
+ return $odd-sum;
+}
+
+#-------------------------------------------------------------------------------
+sub run-tests()
+#-------------------------------------------------------------------------------
+{
+ 'Running the test suite'.put;
+
+ for test-data.lines -> Str $line
+ {
+ my Str ($test-name, $ints-str, $expected) = $line.split: / \| /;
+
+ for $test-name, $ints-str, $expected
+ {
+ s/ ^ \s+ //;
+ s/ \s+ $ //;
+ }
+
+ my Pos @ints = $ints-str.split( / \s+ /, :skip-empty ).map: { .Int };
+ my UInt $sum = find-odd-sum( @ints );
+
+ is $sum, $expected.Int, $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|2 5 3 6 4|77
+ Example 2|1 3 | 4
+ END
+}
+
+################################################################################
diff --git a/challenge-306/athanasius/raku/ch-2.raku b/challenge-306/athanasius/raku/ch-2.raku
new file mode 100644
index 0000000000..769bef5428
--- /dev/null
+++ b/challenge-306/athanasius/raku/ch-2.raku
@@ -0,0 +1,170 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 306
+=========================
+
+TASK #2
+-------
+*Last Element*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given a array of integers, @ints.
+
+Write a script to play a game where you pick two biggest integers in the given
+array, say x and y. Then do the following:
+
+ a) if x == y then remove both from the given array
+ b) if x != y then remove x and replace y with (y - x)
+
+At the end of the game, there is at most one element left.
+
+Return the last element if found otherwise return 0.
+
+Example 1
+
+ Input: @ints = (3, 8, 5, 2, 9, 2)
+ Output: 1
+
+ Step 1: pick 8 and 9 => (3, 5, 2, 1, 2)
+ Step 2: pick 3 and 5 => (2, 2, 1, 2)
+ Step 3: pick 2 and 1 => (1, 2, 2)
+ Step 4: pick 2 and 1 => (1, 2)
+ Step 5: pick 1 and 2 => (1)
+
+Example 2
+
+ Input: @ints = (3, 2, 5)
+ Output: 0
+
+ Step 1: pick 3 and 5 => (2, 2)
+ Step 2: pick 2 and 2 => ()
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2025 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=begin comment
+
+Assumption
+----------
+The input integers are positive (greater than zero).
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. One or more positive integers are entered on the command-line.
+
+=end comment
+#===============================================================================
+
+use Test;
+
+subset Pos of Int where * > 0;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 306, Task #2: Last Element (Raku)\n".put;
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ #| A non-empty list of positive integers
+
+ *@ints where { .elems > 0 && .all ~~ Pos:D }
+)
+#===============================================================================
+{
+ "Input: \@ints = (%s)\n".printf: @ints.join: ', ';
+
+ my UInt $last-element = find-last-element( @ints );
+
+ "Output: $last-element".put;
+}
+
+#===============================================================================
+multi sub MAIN() # No input: run the test suite
+#===============================================================================
+{
+ run-tests();
+}
+
+#-------------------------------------------------------------------------------
+sub find-last-element( List:D[Pos:D] $ints --> UInt:D )
+#-------------------------------------------------------------------------------
+{
+ my Pos @n = $ints.sort;
+
+ while @n.elems > 1
+ {
+ my Pos $y = @n.pop;
+ my Pos $x = @n.pop;
+
+ if $y > $x
+ {
+ @n.push: $y - $x;
+ @n .= sort;
+ }
+ }
+
+ return @n.elems == 0 ?? 0 !! @n[ 0 ];
+}
+
+#-------------------------------------------------------------------------------
+sub run-tests()
+#-------------------------------------------------------------------------------
+{
+ 'Running the test suite'.put;
+
+ for test-data.lines -> Str $line
+ {
+ my Str ($test-name, $ints-str, $expected) =
+ $line.split: / \| /;
+
+ for $test-name, $ints-str, $expected
+ {
+ s/ ^ \s+ //;
+ s/ \s+ $ //;
+ }
+
+ my Pos @ints = $ints-str.split( / \s+ /, :skip-empty ).map: { .Int };
+ my UInt $last = find-last-element( @ints );
+
+ is $last, $expected.Int, $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|3 8 5 2 9 2|1
+ Example 2|3 2 5 |0
+ END
+}
+
+################################################################################