diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2023-11-15 21:26:27 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-11-15 21:26:27 +0000 |
| commit | b3a11494dfbcb9be7052f8f6f32a9afec052485f (patch) | |
| tree | ddea1fb56f7ac3c66533278335befb58c46472bd | |
| parent | 5f91385fd3ff6d559cdb1153dec2fcf612192663 (diff) | |
| parent | cc3037b6e7d60f72ffc1345500d8b733542403da (diff) | |
| download | perlweeklychallenge-club-b3a11494dfbcb9be7052f8f6f32a9afec052485f.tar.gz perlweeklychallenge-club-b3a11494dfbcb9be7052f8f6f32a9afec052485f.tar.bz2 perlweeklychallenge-club-b3a11494dfbcb9be7052f8f6f32a9afec052485f.zip | |
Merge pull request #9074 from PerlMonk-Athanasius/branch-for-challenge-243
Perl & Raku solutions to Tasks 1 & 2 for Week 243
| -rw-r--r-- | challenge-243/athanasius/perl/ch-1.pl | 180 | ||||
| -rw-r--r-- | challenge-243/athanasius/perl/ch-2.pl | 174 | ||||
| -rw-r--r-- | challenge-243/athanasius/raku/ch-1.raku | 183 | ||||
| -rw-r--r-- | challenge-243/athanasius/raku/ch-2.raku | 166 |
4 files changed, 703 insertions, 0 deletions
diff --git a/challenge-243/athanasius/perl/ch-1.pl b/challenge-243/athanasius/perl/ch-1.pl new file mode 100644 index 0000000000..5b88d2e80e --- /dev/null +++ b/challenge-243/athanasius/perl/ch-1.pl @@ -0,0 +1,180 @@ +#!perl + +################################################################################ +=comment + +Perl Weekly Challenge 243 +========================= + +TASK #1 +------- +*Reverse Pairs* + +Submitted by: Mohammad S Anwar + +You are given an array of integers. + +Write a script to return the number of reverse pairs in the given array. + +A reverse pair is a pair (i, j) where: a) 0 <= i < j < nums.length and b) +nums[i] > 2 * nums[j]. + +Example 1 + + Input: @nums = (1, 3, 2, 3, 1) + Output: 2 + + (1, 4) => nums[1] = 3, nums[4] = 1, 3 > 2 * 1 + (3, 4) => nums[3] = 3, nums[4] = 1, 3 > 2 * 1 + +Example 2 + + Input: @nums = (2, 4, 3, 5, 1) + Output: 3 + + (1, 4) => nums[1] = 4, nums[4] = 1, 4 > 2 * 1 + (2, 4) => nums[2] = 3, nums[4] = 1, 3 > 2 * 1 + (3, 4) => nums[3] = 5, nums[4] = 1, 5 > 2 * 1 + +=cut +################################################################################ + +#--------------------------------------# +# Copyright © 2023 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=comment + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. If $VERBOSE is set to a true value, the output is followed by a list of the + reverse pairs found. + +=cut +#=============================================================================== + +use v5.32.1; # Enables strictures +use warnings; +use Const::Fast; +use Regexp::Common qw( number ); +use Test::More; + +const my $VERBOSE => 1; +const my $USAGE => +"Usage: + perl $0 [<nums> ...] + perl $0 + + [<nums> ...] A list of integers\n"; + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + $| = 1; + print "\nChallenge 243, Task #1: Reverse Pairs (Perl)\n\n"; +} + +#=============================================================================== +MAIN: +#=============================================================================== +{ + if (scalar @ARGV == 0) + { + run_tests(); + } + else + { + my @nums = @ARGV; + + for (@nums) + { + / ^ $RE{num}{int} $ /x or error( qq["$_" is not a valid integer] ); + } + + printf "Input: \@nums = (%s)\n", join ', ', @nums; + + my $pairs = find_reverse_pairs( \@nums ); + + printf "Output: %d\n", scalar @$pairs; + + if ($VERBOSE) + { + printf "\nReverse pairs: %s\n", + join ', ', map { '(' . join( ', ', @$_ ) . ')' } @$pairs; + } + } +} + +#------------------------------------------------------------------------------- +sub find_reverse_pairs +#------------------------------------------------------------------------------- +{ + my ($nums) = @_; + my @pairs; + + for my $i (0 .. $#$nums - 1) + { + for my $j ($i + 1 .. $#$nums) + { + if ($nums->[ $i ] > 2 * $nums->[ $j ]) + { + push @pairs, [ $i, $j ]; + } + } + } + + return \@pairs; +} + +#------------------------------------------------------------------------------- +sub run_tests +#------------------------------------------------------------------------------- +{ + print "Running the test suite\n"; + + while (my $line = <DATA>) + { + chomp $line; + + my ($test_name, $nums_str, @exp_strs) = split / \| /x, $line; + + for ($test_name, $nums_str, @exp_strs) + { + s/ ^ \s+ //x; + s/ \s+ $ //x; + } + + my @nums = split / \s+ /x, $nums_str; + my $pairs = find_reverse_pairs( \@nums ); + my @exp; + + for my $exp_str (@exp_strs) + { + push @exp, [ split / \s+ /x, $exp_str ]; + } + + is scalar @$pairs, scalar @exp, $test_name . ': count'; + is_deeply \@$pairs, \@exp, $test_name . ': pairs'; + } + + done_testing; +} + +#------------------------------------------------------------------------------- +sub error +#------------------------------------------------------------------------------- +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +################################################################################ + +__DATA__ +Example 1| 1 3 2 3 1|1 4|3 4 +Example 2| 2 4 3 5 1|1 4|2 4|3 4 +Negatives|-1 0 -2 -1 |0 2|0 3|1 2|1 3 diff --git a/challenge-243/athanasius/perl/ch-2.pl b/challenge-243/athanasius/perl/ch-2.pl new file mode 100644 index 0000000000..ff02128d29 --- /dev/null +++ b/challenge-243/athanasius/perl/ch-2.pl @@ -0,0 +1,174 @@ +#!perl + +################################################################################ +=comment + +Perl Weekly Challenge 243 +========================= + +TASK #2 +------- +*Floor Sum* + +Submitted by: Mohammad S Anwar + +You are given an array of positive integers (>=1). + +Write a script to return the sum of floor(nums[i] / nums[j]) where 0 <= i,j < +nums.length. The floor() function returns the integer part of the division. + +Example 1 + + Input: @nums = (2, 5, 9) + Output: 10 + + floor(2 / 5) = 0 + floor(2 / 9) = 0 + floor(5 / 9) = 0 + floor(2 / 2) = 1 + floor(5 / 5) = 1 + floor(9 / 9) = 1 + floor(5 / 2) = 2 + floor(9 / 2) = 4 + floor(9 / 5) = 1 + +Example 2 + + Input: @nums = (7, 7, 7, 7, 7, 7, 7) + Output: 49 + +=cut +################################################################################ + +#--------------------------------------# +# Copyright © 2023 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=comment + +Interface +--------- +If no command-line arguments are given, the test suite is run. + +=cut +#=============================================================================== + +use v5.32.1; # Enables strictures +use warnings; +use Const::Fast; +use Regexp::Common qw( number ); +use Test::More; + +const my $USAGE => +"Usage: + perl $0 [<nums> ...] + perl $0 + + [<nums> ...] A list of positive integers (>= 1)\n"; + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + $| = 1; + print "\nChallenge 243, Task #2: Floor Sum (Perl)\n\n"; +} + +#=============================================================================== +MAIN: +#=============================================================================== +{ + if (scalar @ARGV == 0) + { + run_tests(); + } + else + { + my $nums = parse_command_line(); + + printf "Input: \@nums = (%s)\n", join ', ', @$nums; + + my $sum = floor_sum( $nums ); + + print "Output: $sum\n"; + } +} + +#------------------------------------------------------------------------------- +sub floor_sum +#------------------------------------------------------------------------------- +{ + my ($nums) = @_; + my $sum = 0; + + for my $i (0 .. $#$nums) + { + for my $j (0 .. $#$nums) + { + # int() is equivalent to floor() when the argument is known to be + # positive + + $sum += int( $nums->[ $i ] / $nums->[ $j ] ); + } + } + + return $sum; +} + +#------------------------------------------------------------------------------- +sub parse_command_line +#------------------------------------------------------------------------------- +{ + for (@ARGV) + { + / ^ $RE{num}{int} $ /x or error( qq["$_" is not a valid integer] ); + + $_ >= 1 or error( qq["$_" is not positive (>= 1)] ); + } + + return \@ARGV; +} + +#------------------------------------------------------------------------------- +sub run_tests +#------------------------------------------------------------------------------- +{ + print "Running the test suite\n"; + + while (my $line = <DATA>) + { + chomp $line; + + my ($test_name, $nums_str, $exp_str) = split / \| /x, $line; + + for ($test_name, $nums_str, $exp_str) + { + s/ ^ \s+ //x; + s/ \s+ $ //x; + } + + my @nums = split / \s+ /x, $nums_str; + my $sum = floor_sum( \@nums ); + + is $sum, $exp_str, $test_name; + } + + done_testing; +} + +#------------------------------------------------------------------------------- +sub error +#------------------------------------------------------------------------------- +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +################################################################################ + +__DATA__ +Example 1|2 5 9 | 10 +Example 2|7 7 7 7 7 7 7 | 49 +Series |1 2 3 4 5 6 7 8 9 10|127 diff --git a/challenge-243/athanasius/raku/ch-1.raku b/challenge-243/athanasius/raku/ch-1.raku new file mode 100644 index 0000000000..7e02672569 --- /dev/null +++ b/challenge-243/athanasius/raku/ch-1.raku @@ -0,0 +1,183 @@ +use v6d; + +################################################################################ +=begin comment + +Perl Weekly Challenge 243 +========================= + +TASK #1 +------- +*Reverse Pairs* + +Submitted by: Mohammad S Anwar + +You are given an array of integers. + +Write a script to return the number of reverse pairs in the given array. + +A reverse pair is a pair (i, j) where: a) 0 <= i < j < nums.length and b) +nums[i] > 2 * nums[j]. + +Example 1 + + Input: @nums = (1, 3, 2, 3, 1) + Output: 2 + + (1, 4) => nums[1] = 3, nums[4] = 1, 3 > 2 * 1 + (3, 4) => nums[3] = 3, nums[4] = 1, 3 > 2 * 1 + +Example 2 + + Input: @nums = (2, 4, 3, 5, 1) + Output: 3 + + (1, 4) => nums[1] = 4, nums[4] = 1, 4 > 2 * 1 + (2, 4) => nums[2] = 3, nums[4] = 1, 3 > 2 * 1 + (3, 4) => nums[3] = 5, nums[4] = 1, 5 > 2 * 1 + +=end comment +################################################################################ + +#--------------------------------------# +# Copyright © 2023 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=begin comment + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. If the first integer is negative, it must be preceded by "--" to indicate + that it is not a command-line flag. +3. If VERBOSE is set to True, the output is followed by a list of the reverse + pairs found. + +=end comment +#=============================================================================== + +use Test; + +my Bool constant VERBOSE = True; + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + "\nChallenge 243, Task #1: Reverse Pairs (Raku)\n".put; +} + +#=============================================================================== +multi sub MAIN +( + *@nums where { .elems > 0 && .all ~~ Int:D } #= A list of integers +) +#=============================================================================== +{ + "Input: \@nums = (%s)\n".printf: @nums.join: ', '; + + my Array[Int] @pairs = find-reverse-pairs( @nums ); + + "Output: %d\n".printf: @pairs.elems; + + if VERBOSE + { + "\nReverse pairs: %s\n".printf: + @pairs.map( { '(' ~ @$_.join( ', ' ) ~ ')' } ).join: ', '; + } +} + +#=============================================================================== +multi sub MAIN() # No input: run the test suite +#=============================================================================== +{ + run-tests(); +} + +#------------------------------------------------------------------------------- +sub find-reverse-pairs( List:D[Int:D] $nums --> List:D[List:D[Int:D]] ) +#------------------------------------------------------------------------------- +{ + my Array[Int] @pairs; + + for 0 .. $nums.end - 1 -> UInt $i + { + for $i + 1 .. $nums.end -> UInt $j + { + if $nums[ $i ] > 2 * $nums[ $j ] + { + @pairs.push: Array[Int].new: $i, $j; + } + } + } + + return @pairs; +} + +#------------------------------------------------------------------------------- +sub run-tests() +#------------------------------------------------------------------------------- +{ + 'Running the test suite'.put; + + for test-data.lines -> Str $line + { + my Str ($test-name, $nums-str, @exp-strs) = $line.split: / \| /; + + for $test-name, $nums-str, @exp-strs + { + s/ ^ \s+ //; + s/ \s+ $ //; + } + + my Int @nums = $nums-str.split( / \s+ / ).map: { .Int }; + my Array[Int] @pairs = find-reverse-pairs( @nums ); + my Array[Int] @exp; + + for @exp-strs -> Str $exp-str + { + @exp.push: Array[Int].new: $exp-str.split( / \s+ / ).map: { .Int }; + } + + is @pairs.elems, @exp.elems, $test-name ~ ': count'; + is-deeply @pairs, @exp, $test-name ~ ': pairs'; + } + + 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 3 2 3 1|1 4|3 4 + Example 2| 2 4 3 5 1|1 4|2 4|3 4 + Negatives|-1 0 -2 -1 |0 2|0 3|1 2|1 3 + END +} + +################################################################################ diff --git a/challenge-243/athanasius/raku/ch-2.raku b/challenge-243/athanasius/raku/ch-2.raku new file mode 100644 index 0000000000..0bb480049e --- /dev/null +++ b/challenge-243/athanasius/raku/ch-2.raku @@ -0,0 +1,166 @@ +use v6d; + +################################################################################ +=begin comment + +Perl Weekly Challenge 243 +========================= + +TASK #2 +------- +*Floor Sum* + +Submitted by: Mohammad S Anwar + +You are given an array of positive integers (>=1). + +Write a script to return the sum of floor(nums[i] / nums[j]) where 0 <= i,j < +nums.length. The floor() function returns the integer part of the division. + +Example 1 + + Input: @nums = (2, 5, 9) + Output: 10 + + floor(2 / 5) = 0 + floor(2 / 9) = 0 + floor(5 / 9) = 0 + floor(2 / 2) = 1 + floor(5 / 5) = 1 + floor(9 / 9) = 1 + floor(5 / 2) = 2 + floor(9 / 2) = 4 + floor(9 / 5) = 1 + +Example 2 + + Input: @nums = (7, 7, 7, 7, 7, 7, 7) + Output: 49 + +=end comment +################################################################################ + +#--------------------------------------# +# Copyright © 2023 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=begin comment + +Interface +--------- +If no command-line arguments are given, the test suite is run. + +=end comment +#=============================================================================== + +use Test; + +subset Pos of Int where * >= 1; + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + "\nChallenge 243, Task #2: Floor Sum (Raku)\n".put; +} + +#=============================================================================== +multi sub MAIN +( + #| A list of positive integers (>= 1) + + *@nums where { .elems > 0 && .all ~~ Pos:D } +) +#=============================================================================== +{ + "Input: \@nums = (%s)\n".printf: @nums.join: ', '; + + my Pos $sum = floor-sum( @nums ); + + "Output: $sum".put; +} + +#=============================================================================== +multi sub MAIN() # No input: run the test suite +#=============================================================================== +{ + run-tests(); +} + +#------------------------------------------------------------------------------- +sub floor-sum( List:D[Pos:D] $nums --> Pos:D ) +#------------------------------------------------------------------------------- +{ + my Pos $sum = Nil; + + for 0 .. $nums.end -> UInt $i + { + for 0 .. $nums.end -> UInt $j + { + $sum += ($nums[ $i ] / $nums[ $j ]).floor; + } + } + + return $sum; +} + +#------------------------------------------------------------------------------- +sub run-tests() +#------------------------------------------------------------------------------- +{ + 'Running the test suite'.put; + + for test-data.lines -> Str $line + { + my Str ($test-name, $nums-str, $exp-str) = $line.split: / \| /; + + for $test-name, $nums-str, $exp-str + { + s/ ^ \s+ //; + s/ \s+ $ //; + } + + my Pos @nums = $nums-str.split( / \s+ / ).map: { .Int }; + my Pos $sum = floor-sum( @nums ); + + is $sum, $exp-str.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|2 5 9 | 10 + Example 2|7 7 7 7 7 7 7 | 49 + Series |1 2 3 4 5 6 7 8 9 10|127 + END +} + +################################################################################ |
