diff options
Diffstat (limited to 'challenge-252')
| -rw-r--r-- | challenge-252/athanasius/perl/ch-1.pl | 169 | ||||
| -rw-r--r-- | challenge-252/athanasius/perl/ch-2.pl | 173 | ||||
| -rw-r--r-- | challenge-252/athanasius/raku/ch-1.raku | 174 | ||||
| -rw-r--r-- | challenge-252/athanasius/raku/ch-2.raku | 159 |
4 files changed, 675 insertions, 0 deletions
diff --git a/challenge-252/athanasius/perl/ch-1.pl b/challenge-252/athanasius/perl/ch-1.pl new file mode 100644 index 0000000000..4484885d9e --- /dev/null +++ b/challenge-252/athanasius/perl/ch-1.pl @@ -0,0 +1,169 @@ +#!perl + +################################################################################ +=comment + +Perl Weekly Challenge 252 +========================= + +TASK #1 +------- +*Special Numbers* + +Submitted by: Mohammad S Anwar + +You are given an array of integers, @ints. + +Write a script to find the sum of the squares of all special elements of the +given array. + + An element $int[i] of @ints is called special if i divides n, i.e. n % i == 0. + Where n is the length of the given array. Also the array is 1-indexed for the + task. + +Example 1 + + Input: @ints = (1, 2, 3, 4) + Output: 21 + + There are exactly 3 special elements in the given array: + $ints[1] since 1 divides 4, + $ints[2] since 2 divides 4, and + $ints[4] since 4 divides 4. + + Hence, the sum of the squares of all special elements of given array: + 1 * 1 + 2 * 2 + 4 * 4 = 21. + +Example 2 + + Input: @ints = (2, 7, 1, 19, 18, 3) + Output: 63 + + There are exactly 4 special elements in the given array: + $ints[1] since 1 divides 6, + $ints[2] since 2 divides 6, + $ints[3] since 3 divides 6, and + $ints[6] since 6 divides 6. + + Hence, the sum of the squares of all special elements of given array: + 2 * 2 + 7 * 7 + 1 * 1 + 3 * 3 = 63 + +=cut +################################################################################ + +#--------------------------------------# +# Copyright © 2024 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 => <<END; +Usage: + perl $0 [<ints> ...] + perl $0 + + [<ints> ...] A non-empty list of integers +END + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + $| = 1; + print "\nChallenge 252, Task #1: Special Numbers (Perl)\n\n"; +} + +#=============================================================================== +MAIN: +#=============================================================================== +{ + if (scalar @ARGV == 0) + { + run_tests(); + } + else + { + my @ints = @ARGV; + + / ^ $RE{num}{int} $ /x or error( qq["$_" is not a valid integer] ) + for @ints; + + printf "Input: \@ints = (%s)\n", join ', ', @ints; + + printf "Output: %d\n", sum_squares_special( \@ints ); + } +} + +#------------------------------------------------------------------------------- +sub sum_squares_special +#------------------------------------------------------------------------------- +{ + my ($ints) = @_; + my $sum = 0; + my $n = scalar @$ints; + + for my $i (0 .. $#$ints) + { + $sum += $ints->[ $i ] ** 2 if $n % ($i + 1) == 0; + } + + return $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 $sum = sum_squares_special( \@ints ); + + is $sum, $expected, $test_name; + } + + done_testing; +} + +#------------------------------------------------------------------------------- +sub error +#------------------------------------------------------------------------------- +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +################################################################################ + +__DATA__ +Example 1| 1 2 3 4 | 21 +Example 2| 2 7 1 19 18 3| 63 +Negatives|-1 -2 -3 -4 | 21 +Singleton|42 |1764 diff --git a/challenge-252/athanasius/perl/ch-2.pl b/challenge-252/athanasius/perl/ch-2.pl new file mode 100644 index 0000000000..0f874f4051 --- /dev/null +++ b/challenge-252/athanasius/perl/ch-2.pl @@ -0,0 +1,173 @@ +#!perl + +################################################################################ +=comment + +Perl Weekly Challenge 252 +========================= + +TASK #2 +------- +*Unique Sum Zero* + +Submitted by: Mohammad S Anwar + +You are given an integer, $n. + +Write a script to find an array containing $n unique integers such that they add +up to zero. + +Example 1 + + Input: $n = 5 + Output: (-7, -1, 1, 3, 4) + + Two other possible solutions could be as below: + (-5, -1, 1, 2, 3) and (-3, -1, 2, -2, 4). + +Example 2 + + Input: $n = 3 + Output: (-1, 0, 1) + +Example 3 + + Input: $n = 1 + Output: (0) + +=cut +################################################################################ + +#--------------------------------------# +# Copyright © 2024 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=comment + +Assumption +---------- +It is assumed that the output list contains at least one element, and therefore +that $n > 0. + +Interface +--------- +1. A single, non-zero, positive integer should be entered on the command-line. +2. No test suite is provided, as the output is randomized. Instead, if the + constant $DEBUG is set to a true value, the generated solution is validated + to ensure that it contains exactly $n unique elements that sum to zero. +3. The constant $COEFF may be adjusted to vary the range of potential output + values. For example, if $n = 4 and $COEFF = 2.5, the integers in the solution + will be drawn from the range -10 .. +10. + +=cut +#=============================================================================== + +use v5.32.1; # Enables strictures +use warnings; +use Const::Fast; +use List::Util qw( none shuffle sum0 ); +use Regexp::Common qw( number ); + +const my $COEFF => 2.5; # Determines the range of possible solution values +const my $DEBUG => 1; + +const my $USAGE => <<END; +Usage: + perl $0 <n> + + <n> A non-zero, positive integer +END + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + $| = 1; + print "\nChallenge 252, Task #2: Unique Sum Zero (Perl)\n\n"; +} + +#=============================================================================== +MAIN: +#=============================================================================== +{ + my $argc = scalar @ARGV; + $argc == 1 or error( "Expected 1 command-line argument, found $argc" ); + + my $n = $ARGV[ 0 ]; + $n =~ / ^ $RE{num}{int} $ /x or error( qq["$n" is not a valid integer] ); + $n > 0 or error( qq["$n" is too small] ); + + print "Input: \$n = $n\n"; + + my $zero_sum_list = find_zero_sum_list( $n ); + + printf "Output: (%s)\n", join ', ', @$zero_sum_list; + + validate( $n, $zero_sum_list ) + or die 'Solution failed validation' if $DEBUG; +} + +#------------------------------------------------------------------------------- +sub find_zero_sum_list +#------------------------------------------------------------------------------- +{ + my ($n) = @_; + my $max = int( $COEFF * $n ); + my @zero_sum_list; + + for (my $done = 0; !$done; ) + { + my @candidates = -$max .. +$max; + @zero_sum_list = (shuffle @candidates)[ 0 .. $n - 2 ]; + my $diff = - sum0 @zero_sum_list; + + # Ensure that $diff is (1) not already in @zero_sum + # and (2) within the specified range + + if ((none { $_ == $diff } @zero_sum_list) && (abs $diff <= $max)) + { + push @zero_sum_list, $diff; + $done = 1; + } + } + + return \@zero_sum_list; +} + +#------------------------------------------------------------------------------- +sub validate +#------------------------------------------------------------------------------- +{ + my ($n, $zero_sum_list) = @_; + + # 1. n elements + + return 0 unless scalar @$zero_sum_list == $n; + + # 2. Unique + + my %dict; + + for my $elem (@$zero_sum_list) + { + return 0 unless ++$dict{ $elem } == 1; + } + + # 3. Add up to zero + + my $sum = sum0 @$zero_sum_list; + + return $sum == 0; +} + +#------------------------------------------------------------------------------- +sub error +#------------------------------------------------------------------------------- +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +################################################################################ diff --git a/challenge-252/athanasius/raku/ch-1.raku b/challenge-252/athanasius/raku/ch-1.raku new file mode 100644 index 0000000000..3b551aa611 --- /dev/null +++ b/challenge-252/athanasius/raku/ch-1.raku @@ -0,0 +1,174 @@ +use v6d; + +################################################################################ +=begin comment + +Perl Weekly Challenge 252 +========================= + +TASK #1 +------- +*Special Numbers* + +Submitted by: Mohammad S Anwar + +You are given an array of integers, @ints. + +Write a script to find the sum of the squares of all special elements of the +given array. + + An element $int[i] of @ints is called special if i divides n, i.e. n % i == 0. + Where n is the length of the given array. Also the array is 1-indexed for the + task. + +Example 1 + + Input: @ints = (1, 2, 3, 4) + Output: 21 + + There are exactly 3 special elements in the given array: + $ints[1] since 1 divides 4, + $ints[2] since 2 divides 4, and + $ints[4] since 4 divides 4. + + Hence, the sum of the squares of all special elements of given array: + 1 * 1 + 2 * 2 + 4 * 4 = 21. + +Example 2 + + Input: @ints = (2, 7, 1, 19, 18, 3) + Output: 63 + + There are exactly 4 special elements in the given array: + $ints[1] since 1 divides 6, + $ints[2] since 2 divides 6, + $ints[3] since 3 divides 6, and + $ints[6] since 6 divides 6. + + Hence, the sum of the squares of all special elements of given array: + 2 * 2 + 7 * 7 + 1 * 1 + 3 * 3 = 63 + +=end comment +################################################################################ + +#--------------------------------------# +# Copyright © 2024 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=begin comment + +Interface +--------- +1. If no command-line arguments are given, the test suite is run. Otherwise: +2. If the first command-line argument is negative, it must be preceded by "--" + to distinguish it from a command-line switch. + +=end comment +#=============================================================================== + +use Test; + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + "\nChallenge 252, Task #1: Special Numbers (Raku)\n".put; +} + +#=============================================================================== +multi sub MAIN +( + #| A non-empty list if integers + + *@ints where { .elems > 0 && .all ~~ Int:D } +) +#=============================================================================== +{ + "Input: \@ints = (%s)\n".printf: @ints.join: ', '; + + "Output: %d\n".printf: sum-squares-special( @ints ); +} + +#=============================================================================== +multi sub MAIN() # No input: run the test suite +#=============================================================================== +{ + run-tests(); +} + +#------------------------------------------------------------------------------- +sub sum-squares-special( List:D[Int:D] $ints where { .elems > 0 } --> UInt:D ) +#------------------------------------------------------------------------------- +{ + my UInt $sum = 0; + my UInt $n = $ints.elems; + + for 0 .. $ints.end -> UInt $i + { + $sum += $ints[ $i ]² if $n %% ($i + 1); + } + + return $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 Int @ints = $ints-str.split( / \s+ / ).map: { .Int }; + my UInt $sum = sum-squares-special( @ints ); + + is $sum, $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 4 | 21 + Example 2| 2 7 1 19 18 3| 63 + Negatives|-1 -2 -3 -4 | 21 + Singleton|42 |1764 + END +} + +################################################################################ diff --git a/challenge-252/athanasius/raku/ch-2.raku b/challenge-252/athanasius/raku/ch-2.raku new file mode 100644 index 0000000000..278591a5a9 --- /dev/null +++ b/challenge-252/athanasius/raku/ch-2.raku @@ -0,0 +1,159 @@ +use v6d; + +################################################################################ +=begin comment + +Perl Weekly Challenge 252 +========================= + +TASK #2 +------- +*Unique Sum Zero* + +Submitted by: Mohammad S Anwar + +You are given an integer, $n. + +Write a script to find an array containing $n unique integers such that they add +up to zero. + +Example 1 + + Input: $n = 5 + Output: (-7, -1, 1, 3, 4) + + Two other possible solutions could be as below: + (-5, -1, 1, 2, 3) and (-3, -1, 2, -2, 4). + +Example 2 + + Input: $n = 3 + Output: (-1, 0, 1) + +Example 3 + + Input: $n = 1 + Output: (0) + +=end comment +################################################################################ + +#--------------------------------------# +# Copyright © 2024 PerlMonk Athanasius # +#--------------------------------------# + +#=============================================================================== +=begin comment + +Assumption +---------- +It is assumed that the output list contains at least one element, and therefore +that $n > 0. + +Interface +--------- +1. A single, non-zero, positive integer should be entered on the command-line. +2. No test suite is provided, as the output is randomized. Instead, if the + constant DEBUG is set to True, the generated solution is validated to ensure + that it contains exactly $n unique elements that sum to zero. +3. The constant COEFF may be adjusted to vary the range of potential output + values. For example, if $n = 4 and COEFF = 2.5, the integers in the solution + will be drawn from the range -10 .. +10. + +=end comment +#=============================================================================== + +use List::Util < shuffle >; + +subset Pos of Int where * > 0; + +my Rat constant COEFF = 2.5; # Determines range of possible solution values +my Bool constant DEBUG = True; + +#------------------------------------------------------------------------------- +BEGIN +#------------------------------------------------------------------------------- +{ + "\nChallenge 252, Task #2: Unique Sum Zero (Raku)\n".put; +} + +#=============================================================================== +sub MAIN +( + Pos:D $n #= A non-zero, positive integer +) +#=============================================================================== +{ + "Input: \$n = $n".put; + + my Int @zero-sum-list = find-zero-sum-list( $n ); + + "Output: (%s)\n".printf: @zero-sum-list.join: ', '; + + validate( $n, @zero-sum-list ) or die 'Solution failed validation' if DEBUG; +} + +#------------------------------------------------------------------------------- +sub find-zero-sum-list( Pos:D $n --> List:D[Int:D] ) +#------------------------------------------------------------------------------- +{ + my Int @zero-sum-list; + my UInt $max = (COEFF * $n).floor; + + loop (my Bool $done = False; !$done; ) + { + my Int @candidates = -$max .. +$max; + + @zero-sum-list = (shuffle @candidates)[ 0 .. $n - 2 ]; + + my Int $diff = - [+] @zero-sum-list; + + # Ensure that $diff is (1) not already in @zero-sum + # and (2) within the specified range + + if @zero-sum-list.none == $diff && $diff.abs <= $max + { + @zero-sum-list.push: $diff; + $done = True; + } + } + + return @zero-sum-list; +} + +#------------------------------------------------------------------------------- +sub validate( Pos:D $n, List:D[Int:D] $zero-sum-list --> Bool:D ) +#------------------------------------------------------------------------------- +{ + # 1. n elements + + return False unless $zero-sum-list.elems == $n; + + # 2. Unique + + my Pos %dict{Int}; + + for @$zero-sum-list -> Int $elem + { + return False unless ++%dict{ $elem } == 1; + } + + # 3. Add up to zero + + my Int $sum = [+] @$zero-sum-list; + + return $sum == 0; +} + +#------------------------------------------------------------------------------- +sub USAGE() +#------------------------------------------------------------------------------- +{ + my Str $usage = $*USAGE; + + $usage ~~ s:g/ ($*PROGRAM-NAME) /raku $0/; + + $usage.put; +} + +################################################################################ |
