aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com>2024-03-21 13:52:59 +1000
committerPerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com>2024-03-21 13:52:59 +1000
commit4437659cce3864d62774fddb7d0bc8d3f8ed25e0 (patch)
tree59edbb288bd1daaed774d878bf242b06697a3ba9
parent5bdb6ed8347dae7adc19d0403759d70f47f047fc (diff)
downloadperlweeklychallenge-club-4437659cce3864d62774fddb7d0bc8d3f8ed25e0.tar.gz
perlweeklychallenge-club-4437659cce3864d62774fddb7d0bc8d3f8ed25e0.tar.bz2
perlweeklychallenge-club-4437659cce3864d62774fddb7d0bc8d3f8ed25e0.zip
Perl & Raku solutions to Tasks 1 & 2 for Week 261
-rw-r--r--challenge-261/athanasius/perl/ch-1.pl183
-rw-r--r--challenge-261/athanasius/perl/ch-2.pl206
-rw-r--r--challenge-261/athanasius/raku/ch-1.raku188
-rw-r--r--challenge-261/athanasius/raku/ch-2.raku181
4 files changed, 758 insertions, 0 deletions
diff --git a/challenge-261/athanasius/perl/ch-1.pl b/challenge-261/athanasius/perl/ch-1.pl
new file mode 100644
index 0000000000..d54819236d
--- /dev/null
+++ b/challenge-261/athanasius/perl/ch-1.pl
@@ -0,0 +1,183 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 261
+=========================
+
+TASK #1
+-------
+*Element Digit Sum*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of integers, @ints.
+
+Write a script to evaluate the absolute difference between element and digit sum
+of the given array.
+
+Example 1
+
+ Input: @ints = (1,2,3,45)
+ Output: 36
+
+ Element Sum: 1 + 2 + 3 + 45 = 51
+ Digit Sum: 1 + 2 + 3 + 4 + 5 = 15
+ Absolute Difference: | 51 - 15 | = 36
+
+Example 2
+
+ Input: @ints = (1,12,3)
+ Output: 9
+
+ Element Sum: 1 + 12 + 3 = 16
+ Digit Sum: 1 + 1 + 2 + 3 = 7
+ Absolute Difference: | 16 - 7 | = 9
+
+Example 3
+
+ Input: @ints = (1,2,3,4)
+ Output: 0
+
+ Element Sum: 1 + 2 + 3 + 4 = 10
+ Digit Sum: 1 + 2 + 3 + 4 = 10
+ Absolute Difference: | 10 - 10 | = 0
+
+Example 4
+
+ Input: @ints = (236, 416, 336, 350)
+ Output: 1296
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2024 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=comment
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. One or more integers are given as arguments on the command-line.
+
+Assumption
+----------
+For the purpose of calculating the digit sum, only digits 1 to 9 and 0 are used:
+the signs "+" and "-" are ignored. However, negative numbers remain negative for
+the purpose of calculating the element sum.
+
+=cut
+#===============================================================================
+
+use v5.32.1; # 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 integers
+END
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 261, Task #1: Element Digit 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] );
+ }
+
+ printf "Input: \@ints = (%s)\n", join ',', @ints;
+
+ my $diff = find_difference( \@ints );
+
+ print "Output: $diff\n";
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub find_difference
+#-------------------------------------------------------------------------------
+{
+ my ($ints) = @_;
+ my $element_sum = 0;
+ $element_sum += $_ for @$ints;
+ my $digit_sum = 0;
+
+ for my $element (@$ints)
+ {
+ $digit_sum += $_ for grep { / ^ \d $ /x } split //, $element;
+ }
+
+ return abs( $element_sum - $digit_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 $diff = find_difference( \@ints );
+
+ is $diff, $expected, $test_name;
+ }
+
+ done_testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+################################################################################
+
+__DATA__
+Example 1| 1 2 3 45| 36
+Example 2| 1 12 3 | 9
+Example 3| 1 2 3 4| 0
+Example 4|236 416 336 350|1296
+Signed | -1 +34 -2 +2| 21
diff --git a/challenge-261/athanasius/perl/ch-2.pl b/challenge-261/athanasius/perl/ch-2.pl
new file mode 100644
index 0000000000..6b0ed2aa9a
--- /dev/null
+++ b/challenge-261/athanasius/perl/ch-2.pl
@@ -0,0 +1,206 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 261
+=========================
+
+TASK #2
+-------
+*Multiply by Two*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of integers, @ints and an integer $start..
+
+Write a script to do the followings:
+
+ a) Look for $start in the array @ints, if found multiply the number by 2
+ b) If not found stop the process otherwise repeat
+
+In the end return the final value.
+
+Example 1
+
+ Input: @ints = (5,3,6,1,12) and $start = 3
+ Output: 24
+
+ Step 1: 3 is in the array so 3 x 2 = 6
+ Step 2: 6 is in the array so 6 x 2 = 12
+ Step 3: 12 is in the array so 12 x 2 = 24
+
+ 24 is not found in the array so return 24.
+
+Example 2
+
+ Input: @ints = (1,2,4,3) and $start = 1
+ Output: 8
+
+ Step 1: 1 is in the array so 1 x 2 = 2
+ Step 2: 2 is in the array so 2 x 2 = 4
+ Step 3: 4 is in the array so 4 x 2 = 8
+
+ 8 is not found in the array so return 8.
+
+Example 3
+
+ Input: @ints = (5,6,7) and $start = 2
+ Output: 2
+
+ 2 is not found in the array so return 2.
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2024 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=comment
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. The starting integer is given on the command-line as a named argument,
+ followed by a (possibly empty) list of integers.
+3. If any integers in the list (i.e., following the start integer) on the
+ command-line are either negative or preceded by an explicit "+" sign, the
+ list must be preceded by "--" to indicate that the signed integers are not
+ command-line flags.
+
+=cut
+#===============================================================================
+
+use v5.32.1; # Enables strictures
+use warnings;
+use Const::Fast;
+use Getopt::Long;
+use List::Util qw( any );
+use Regexp::Common qw( number );
+use Test::More;
+
+const my $USAGE => <<END;
+Usage:
+ perl $0 [--start[=Int]] [<ints> ...]
+ perl $0
+
+ --start[=Int] The starting integer
+ [<ints> ...] A list of integers
+END
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 261, Task #2: Multiply by Two (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ if (scalar @ARGV == 0)
+ {
+ run_tests();
+ }
+ else
+ {
+ my ($start, $ints) = parse_command_line();
+
+ printf "Input: \@ints = (%s) and start = %d\n",
+ join( ',', @$ints ), $start;
+
+ printf "Output: %d\n", find_final_value( $ints, $start );
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub find_final_value
+#-------------------------------------------------------------------------------
+{
+ my ($ints, $start) = @_;
+
+ my $value = $start;
+
+ if ($start != 0)
+ {
+ $value *= 2 while any { $_ == $value } @$ints;
+ }
+
+ return $value;
+}
+
+#-------------------------------------------------------------------------------
+sub parse_command_line
+#-------------------------------------------------------------------------------
+{
+ my $start;
+
+ GetOptions( 'start=i' => \$start )
+ or error( 'Invalid command-line argument' );
+
+ defined $start or error( '$start is missing' );
+
+ $start =~ / ^ $RE{num}{int} $ /x
+ or error( qq[start ("$start") is not a valid integer] );
+
+ my @ints = @ARGV;
+
+ for (@ints)
+ {
+ / ^ $RE{num}{int} $ /x
+ or error( qq["$_" is not a valid integer] );
+ }
+
+ return ($start, \@ints);
+}
+
+#-------------------------------------------------------------------------------
+sub run_tests
+#-------------------------------------------------------------------------------
+{
+ print "Running the test suite\n";
+
+ while (my $line = <DATA>)
+ {
+ chomp $line;
+
+ my ($test_name, $ints_str, $start, $expected) = split / \| /x, $line;
+
+ for ($test_name, $ints_str, $start, $expected)
+ {
+ s/ ^ \s+ //x;
+ s/ \s+ $ //x;
+ }
+
+ my @ints = split / \s+ /x, $ints_str;
+ my $value = find_final_value( \@ints, $start );
+
+ is $value, $expected, $test_name;
+ }
+
+ done_testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+################################################################################
+
+__DATA__
+Example 1 |5 3 6 1 12 | 3|24
+Example 2 |1 2 4 3 | 1| 8
+Example 3 |5 6 7 | 2| 2
+Negatives |7 -2 0 -1 3 |-1|-4
+Repetitions|4 8 16 4 32 8| 4|64
+Zero start |9 -3 1 17 0 | 0| 0
+Empty list | |42|42
diff --git a/challenge-261/athanasius/raku/ch-1.raku b/challenge-261/athanasius/raku/ch-1.raku
new file mode 100644
index 0000000000..c095512049
--- /dev/null
+++ b/challenge-261/athanasius/raku/ch-1.raku
@@ -0,0 +1,188 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 261
+=========================
+
+TASK #1
+-------
+*Element Digit Sum*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of integers, @ints.
+
+Write a script to evaluate the absolute difference between element and digit sum
+of the given array.
+
+Example 1
+
+ Input: @ints = (1,2,3,45)
+ Output: 36
+
+ Element Sum: 1 + 2 + 3 + 45 = 51
+ Digit Sum: 1 + 2 + 3 + 4 + 5 = 15
+ Absolute Difference: | 51 - 15 | = 36
+
+Example 2
+
+ Input: @ints = (1,12,3)
+ Output: 9
+
+ Element Sum: 1 + 12 + 3 = 16
+ Digit Sum: 1 + 1 + 2 + 3 = 7
+ Absolute Difference: | 16 - 7 | = 9
+
+Example 3
+
+ Input: @ints = (1,2,3,4)
+ Output: 0
+
+ Element Sum: 1 + 2 + 3 + 4 = 10
+ Digit Sum: 1 + 2 + 3 + 4 = 10
+ Absolute Difference: | 10 - 10 | = 0
+
+Example 4
+
+ Input: @ints = (236, 416, 336, 350)
+ Output: 1296
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2024 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=begin comment
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. One or more integers are given as arguments on the command-line.
+3. If the first integer is negative, it must be preceded by "--" to indicate
+ that it is not a command-line flag.
+
+Assumption
+----------
+For the purpose of calculating the digit sum, only digits 1 to 9 and 0 are used:
+the signs "+" and "-" are ignored. However, negative numbers remain negative for
+the purpose of calculating the element sum.
+
+=end comment
+#===============================================================================
+
+use Test;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 261, Task #1: Element Digit Sum (Raku)\n".put;
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ #| A non-empty list of integers
+
+ *@ints where { .elems > 0 && .all ~~ Int:D }
+)
+#===============================================================================
+{
+ "Input: \@ints = (%s)\n".printf: @ints.join: ',';
+
+ my UInt $diff = find-difference( @ints );
+
+ "Output: $diff".put;
+}
+
+#===============================================================================
+multi sub MAIN() # No input: run the test suite
+#===============================================================================
+{
+ run-tests();
+}
+
+#-------------------------------------------------------------------------------
+sub find-difference( List:D[Int:D] $ints where { .elems > 0 } --> UInt:D )
+#-------------------------------------------------------------------------------
+{
+ my Int $element-sum = [+] @$ints;
+ my UInt $digit-sum = 0;
+
+ for @$ints -> Int $element
+ {
+ for $element.split( '', :skip-empty ).grep: { / ^ \d $/ }
+ {
+ $digit-sum += $_;
+ }
+ }
+
+ return ($element-sum - $digit-sum).abs;
+}
+
+#-------------------------------------------------------------------------------
+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 Int @ints = $ints-str.split( / \s+ /, :skip-empty ).map: { .Int };
+ my UInt $diff = find-difference( @ints );
+
+ is $diff, $expected.Int, $test-name;
+ }
+
+ done-testing;
+}
+
+#-------------------------------------------------------------------------------
+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| 1 2 3 45| 36
+ Example 2| 1 12 3 | 9
+ Example 3| 1 2 3 4| 0
+ Example 4|236 416 336 350|1296
+ Signed | -1 +34 -2 +2| 21
+ END
+}
+
+################################################################################
diff --git a/challenge-261/athanasius/raku/ch-2.raku b/challenge-261/athanasius/raku/ch-2.raku
new file mode 100644
index 0000000000..e00470ff44
--- /dev/null
+++ b/challenge-261/athanasius/raku/ch-2.raku
@@ -0,0 +1,181 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 261
+=========================
+
+TASK #2
+-------
+*Multiply by Two*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of integers, @ints and an integer $start..
+
+Write a script to do the followings:
+
+ a) Look for $start in the array @ints, if found multiply the number by 2
+ b) If not found stop the process otherwise repeat
+
+In the end return the final value.
+
+Example 1
+
+ Input: @ints = (5,3,6,1,12) and $start = 3
+ Output: 24
+
+ Step 1: 3 is in the array so 3 x 2 = 6
+ Step 2: 6 is in the array so 6 x 2 = 12
+ Step 3: 12 is in the array so 12 x 2 = 24
+
+ 24 is not found in the array so return 24.
+
+Example 2
+
+ Input: @ints = (1,2,4,3) and $start = 1
+ Output: 8
+
+ Step 1: 1 is in the array so 1 x 2 = 2
+ Step 2: 2 is in the array so 2 x 2 = 4
+ Step 3: 4 is in the array so 4 x 2 = 8
+
+ 8 is not found in the array so return 8.
+
+Example 3
+
+ Input: @ints = (5,6,7) and $start = 2
+ Output: 2
+
+ 2 is not found in the array so return 2.
+
+=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 starting integer is given on the command-line as a named argument,
+ followed by a (possibly empty) list of integers.
+3. If the first integer in the list (i.e., following the start integer) on the
+ command-line is negative, it must be preceded by "--" to indicate that it is
+ not a command-line flag.
+
+=end comment
+#===============================================================================
+
+use Test;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 261, Task #2: Multiply by Two (Raku)\n".put;
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ Int:D :$start, #= The starting integer
+ *@ints where { .all ~~ Int:D } #= A list of integers
+)
+#===============================================================================
+{
+ "Input: \@ints = (%s) and start = %d\n".printf: @ints.join( ',' ), $start;
+
+ "Output: %d\n".printf: find-final-value( @ints, $start );
+}
+
+#===============================================================================
+multi sub MAIN() # No input: run the test suite
+#===============================================================================
+{
+ run-tests();
+}
+
+#-------------------------------------------------------------------------------
+sub find-final-value( List:D[Int:D] $ints, Int:D $start --> Int:D )
+#-------------------------------------------------------------------------------
+{
+ my Int $value = $start;
+
+ if $start ≠ 0
+ {
+ $value *= 2 while $value == $ints.any;
+ }
+
+ return $value;
+}
+
+#-------------------------------------------------------------------------------
+sub run-tests()
+#-------------------------------------------------------------------------------
+{
+ 'Running the test suite'.put;
+
+ for test-data.lines -> Str $line
+ {
+ my Str ($test-name, $ints-str, $start-str, $expected) =
+ $line.split: / \| /;
+
+ for $test-name, $ints-str, $start-str, $expected
+ {
+ s/ ^ \s+ //;
+ s/ \s+ $ //;
+ }
+
+ my Int @ints = $ints-str.split( / \s+ /, :skip-empty ).map: { .Int };
+ my Int $value = find-final-value( @ints, $start-str.Int );
+
+ is $value, $expected.Int, $test-name;
+ }
+
+ done-testing;
+}
+
+#-------------------------------------------------------------------------------
+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 |5 3 6 1 12 | 3|24
+ Example 2 |1 2 4 3 | 1| 8
+ Example 3 |5 6 7 | 2| 2
+ Negatives |7 -2 0 -1 3 |-1|-4
+ Repetitions|4 8 16 4 32 8| 4|64
+ Zero start |9 -3 1 17 0 | 0| 0
+ Empty list | |42|42
+ END
+}
+
+################################################################################