aboutsummaryrefslogtreecommitdiff
path: root/challenge-252
diff options
context:
space:
mode:
Diffstat (limited to 'challenge-252')
-rw-r--r--challenge-252/athanasius/perl/ch-1.pl169
-rw-r--r--challenge-252/athanasius/perl/ch-2.pl173
-rw-r--r--challenge-252/athanasius/raku/ch-1.raku174
-rw-r--r--challenge-252/athanasius/raku/ch-2.raku159
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;
+}
+
+################################################################################