diff options
| author | PerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com> | 2024-03-21 13:52:59 +1000 |
|---|---|---|
| committer | PerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com> | 2024-03-21 13:52:59 +1000 |
| commit | 4437659cce3864d62774fddb7d0bc8d3f8ed25e0 (patch) | |
| tree | 59edbb288bd1daaed774d878bf242b06697a3ba9 | |
| parent | 5bdb6ed8347dae7adc19d0403759d70f47f047fc (diff) | |
| download | perlweeklychallenge-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.pl | 183 | ||||
| -rw-r--r-- | challenge-261/athanasius/perl/ch-2.pl | 206 | ||||
| -rw-r--r-- | challenge-261/athanasius/raku/ch-1.raku | 188 | ||||
| -rw-r--r-- | challenge-261/athanasius/raku/ch-2.raku | 181 |
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 +} + +################################################################################ |
