aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com>2023-02-26 18:40:58 +1000
committerPerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com>2023-02-26 18:40:58 +1000
commit67ed83401d2b7e77caa48b9fd76b6da9be91f4bc (patch)
tree71f2ce19840621d15cef5912c7d82fe85120c816
parentb284f024a9a0fb134828bfaba21aa1d5354ac2f7 (diff)
downloadperlweeklychallenge-club-67ed83401d2b7e77caa48b9fd76b6da9be91f4bc.tar.gz
perlweeklychallenge-club-67ed83401d2b7e77caa48b9fd76b6da9be91f4bc.tar.bz2
perlweeklychallenge-club-67ed83401d2b7e77caa48b9fd76b6da9be91f4bc.zip
Perl & Raku solutions to Tasks 1 & 2 for Week 205
-rw-r--r--challenge-205/athanasius/perl/ch-1.pl143
-rw-r--r--challenge-205/athanasius/perl/ch-2.pl212
-rw-r--r--challenge-205/athanasius/raku/ch-1.raku146
-rw-r--r--challenge-205/athanasius/raku/ch-2.raku200
4 files changed, 701 insertions, 0 deletions
diff --git a/challenge-205/athanasius/perl/ch-1.pl b/challenge-205/athanasius/perl/ch-1.pl
new file mode 100644
index 0000000000..150f4f8864
--- /dev/null
+++ b/challenge-205/athanasius/perl/ch-1.pl
@@ -0,0 +1,143 @@
+#!perl
+
+###############################################################################
+=comment
+
+Perl Weekly Challenge 205
+=========================
+
+TASK #1
+-------
+*Third Highest*
+
+Submitted by: Mohammad S Anwar
+
+You are given an array of integers.
+
+Write a script to find out the Third Highest if found otherwise return the
+maximum.
+
+Example 1
+
+ Input: @array = (5,3,4)
+ Output: 3
+
+ First highest is 5. Second highest is 4. Third highest is 3.
+
+Example 2
+
+ Input: @array = (5,6)
+ Output: 6
+
+ First highest is 6. Second highest is 5. Third highest is missing, so maximum
+ is returned.
+
+Example 3
+
+ Input: @array = (5,4,4,3)
+ Output: 3
+
+ First highest is 5. Second highest is 4. Third highest is 3.
+
+=cut
+###############################################################################
+
+#--------------------------------------#
+# Copyright © 2023 PerlMonk Athanasius #
+#--------------------------------------#
+
+#==============================================================================
+=comment
+
+Interface
+---------
+If no command-line arguments are given, the test suite is run.
+
+=cut
+#==============================================================================
+
+use strict;
+use warnings;
+use Const::Fast;
+use Regexp::Common qw( number );
+use Test::More;
+
+const my $USAGE =>
+"Usage:
+ perl $0 [<array> ...]
+ perl $0
+
+ [<array> ...] A list of 1 or more integers\n";
+
+#------------------------------------------------------------------------------
+BEGIN
+#------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 205, Task #1: Third Highest (Perl)\n\n";
+}
+
+#==============================================================================
+MAIN:
+#==============================================================================
+{
+ if (scalar @ARGV == 0)
+ {
+ run_tests();
+ }
+ else
+ {
+ my @array = map { $_ + 0 } @ARGV; # Normalize
+
+ / ^ $RE{num}{int} $ /x
+ or die qq[ERROR: "$_" is not a valid integer\n$USAGE]
+ for @array;
+
+ printf "Input: \@array = (%s)\n", join ',', @array;
+
+ printf "Output: %d\n", find_third_highest( \@array );
+ }
+}
+
+#------------------------------------------------------------------------------
+sub find_third_highest
+#------------------------------------------------------------------------------
+{
+ my ($array) = @_;
+ my %count;
+
+ ++$count{ $_ } for @$array;
+
+ my @sorted = sort { $a <=> $b } keys %count;
+
+ return scalar( @sorted ) >= 3 ? $sorted[ -3 ] : $sorted[ -1 ];
+}
+
+#------------------------------------------------------------------------------
+sub run_tests
+#------------------------------------------------------------------------------
+{
+ print "Running the test suite\n";
+
+ while (my $line = <DATA>)
+ {
+ chomp $line;
+
+ my ($test_name, $input, $expected) = split / \| /x, $line;
+
+ my @array = map { $_ + 0 } split / , \s* /x, $input;
+ my $got = find_third_highest( \@array );
+
+ is $got, $expected + 0, $test_name;
+ }
+
+ done_testing;
+}
+
+###############################################################################
+
+__DATA__
+Example 1| 5, 3, 4 | 3
+Example 2| 5, 6 | 6
+Example 3| 5, 4, 4, 3 | 3
+Negatives|-1,-2,-3,-4,-2|-3
diff --git a/challenge-205/athanasius/perl/ch-2.pl b/challenge-205/athanasius/perl/ch-2.pl
new file mode 100644
index 0000000000..c4e33f8e00
--- /dev/null
+++ b/challenge-205/athanasius/perl/ch-2.pl
@@ -0,0 +1,212 @@
+#!perl
+
+###############################################################################
+=comment
+
+Perl Weekly Challenge 205
+=========================
+
+TASK #2
+-------
+*Maximum XOR*
+
+Submitted by: Mohammad S Anwar
+
+You are given an array of integers.
+
+Write a script to find the highest value obtained by XORing any two distinct
+members of the array.
+
+Example 1
+
+ Input: @array = (1,2,3,4,5,6,7)
+ Output: 7
+
+ The maximum result of 1 xor 6 = 7.
+
+Example 2
+
+ Input: @array = (2,4,1,3)
+ Output: 7
+
+ The maximum result of 4 xor 3 = 7.
+
+Example 3
+
+ Input: @array = (10,5,7,12,8)
+ Output: 15
+
+ The maximum result of 10 xor 5 = 15.
+
+=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, then the output is augmented with an
+ explanation of how the result was obtained.
+
+Assumption
+----------
+The elements of the input array are *non-negative* integers only, as shown in
+the examples.
+
+=cut
+#==============================================================================
+
+use strict;
+use warnings;
+use Const::Fast;
+use Regexp::Common qw( number );
+use Test::More;
+
+const my $VERBOSE => 1;
+const my $USAGE =>
+"Usage:
+ perl $0 [<array> ...]
+ perl $0
+
+ [<array> ...] A list of non-negative integers, at least 2 distinct\n";
+
+#------------------------------------------------------------------------------
+BEGIN
+#------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 205, Task #2: Maximum XOR (Perl)\n\n";
+}
+
+#==============================================================================
+MAIN:
+#==============================================================================
+{
+ if (scalar @ARGV == 0)
+ {
+ run_tests();
+ }
+ else
+ {
+ my $array = parse_command_line();
+
+ printf "Input: \@array = (%s)\n", join ',', @$array;
+
+ my ($xor, $a, $b) = find_xor_max( $array );
+
+ print "Output: $xor\n";
+
+ if ($VERBOSE)
+ {
+ my $len_a = length sprintf '%b', $a;
+ my $len_b = length sprintf '%b', $b;
+ my $width = ($len_a >= $len_b) ? $len_a : $len_b;
+
+ printf "\nThe maximum result of %*d xor %*d = %*d\n",
+ $width, $a, $width, $b, $width, $xor;
+
+ printf " (binary: %0*b xor %0*b = %0*b)\n",
+ $width, $a, $width, $b, $width, $xor;
+ }
+ }
+}
+
+#------------------------------------------------------------------------------
+sub find_xor_max
+#------------------------------------------------------------------------------
+{
+ my ($array) = @_;
+
+ my %freq;
+ ++$freq{ $_ } for @$array;
+
+ my @ordered = sort { $a <=> $b } keys %freq;
+
+ scalar @ordered >= 2
+ or error( 'The input array does not contain 2 distinct members' );
+
+ my $xor_max = -1;
+ my ($a_max, $b_max);
+
+ for my $i (0 .. $#ordered - 1)
+ {
+ my $aa = $ordered[ $i ];
+
+ for my $j ($i + 1 .. $#ordered)
+ {
+ my $bb = $ordered[ $j ];
+ my $xor = $aa ^ $bb;
+
+ if ($xor > $xor_max)
+ {
+ $xor_max = $xor;
+ $a_max = $aa;
+ $b_max = $bb;
+ }
+ }
+ }
+
+ return ($xor_max, $a_max, $b_max);
+}
+
+#------------------------------------------------------------------------------
+sub parse_command_line
+#------------------------------------------------------------------------------
+{
+ my $args = scalar @ARGV;
+ $args >= 2 or error( 'Expected at least 2 command-line arguments, ' .
+ "found $args" );
+
+ for (@ARGV)
+ {
+ / ^ $RE{num}{int} $ /x
+ or error( qq["$_" is not a valid integer] );
+
+ $_ >= 0 or error( qq["$_" is negative] );
+ }
+
+ return [ @ARGV ];
+}
+
+#------------------------------------------------------------------------------
+sub run_tests
+#------------------------------------------------------------------------------
+{
+ print "Running the test suite\n";
+
+ while (my $line = <DATA>)
+ {
+ chomp $line;
+
+ my ($test_name, $input, $expected) = split / \| /x, $line;
+
+ my @array = split / \, \s* /x, $input;
+ my $got = (find_xor_max( \@array ))[ 0 ];
+
+ is $got, $expected, $test_name;
+ }
+
+ done_testing;
+}
+
+#------------------------------------------------------------------------------
+sub error
+#------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+###############################################################################
+
+__DATA__
+Example 1| 1, 2, 3, 4, 5, 6, 7|7
+Example 2| 2, 4, 1, 3 |7
+Example 3|10, 5, 7, 12, 8 |15
diff --git a/challenge-205/athanasius/raku/ch-1.raku b/challenge-205/athanasius/raku/ch-1.raku
new file mode 100644
index 0000000000..3f7f83eaa4
--- /dev/null
+++ b/challenge-205/athanasius/raku/ch-1.raku
@@ -0,0 +1,146 @@
+use v6d;
+
+###############################################################################
+=begin comment
+
+Perl Weekly Challenge 205
+=========================
+
+TASK #1
+-------
+*Third Highest*
+
+Submitted by: Mohammad S Anwar
+
+You are given an array of integers.
+
+Write a script to find out the Third Highest if found otherwise return the
+maximum.
+
+Example 1
+
+ Input: @array = (5,3,4)
+ Output: 3
+
+ First highest is 5. Second highest is 4. Third highest is 3.
+
+Example 2
+
+ Input: @array = (5,6)
+ Output: 6
+
+ First highest is 6. Second highest is 5. Third highest is missing, so maximum
+ is returned.
+
+Example 3
+
+ Input: @array = (5,4,4,3)
+ Output: 3
+
+ First highest is 5. Second highest is 4. Third highest is 3.
+
+=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 argument is negative, it must be preceded by "--" to distin-
+ guish it from a command-line flag.
+
+=end comment
+#==============================================================================
+
+use Test;
+
+#------------------------------------------------------------------------------
+BEGIN
+#------------------------------------------------------------------------------
+{
+ "\nChallenge 205, Task #1: Third Highest (Raku)\n".put;
+}
+
+#==============================================================================
+multi sub MAIN
+(
+ #| A list of 1 or more integers
+
+ *@array where { .elems >= 1 && .all ~~ Int:D }
+)
+#==============================================================================
+{
+ "Input: \@array = (%s)\n".printf: @array.join: ',';
+
+ "Output: %d\n".printf: find-third-highest( @array );
+}
+
+#==============================================================================
+multi sub MAIN() # No input: run the test suite
+#==============================================================================
+{
+ run-tests();
+}
+
+#------------------------------------------------------------------------------
+sub find-third-highest( List:D[Int:D] $array where { .elems > 0 } --> Int:D )
+#------------------------------------------------------------------------------
+{
+ my UInt %count{Int};
+
+ ++%count{ $_ } for @$array;
+
+ my Int @sorted = %count<>:k.sort;
+
+ return @sorted.elems >= 3 ?? @sorted[ *-3 ] !! @sorted[ *-1 ];
+}
+
+#------------------------------------------------------------------------------
+sub run-tests()
+#------------------------------------------------------------------------------
+{
+ 'Running the test suite'.put;
+
+ for test-data.lines -> Str $line
+ {
+ my Str ($test-name, $input, $expected) = $line.split: / \| /;
+
+ my Int @array = $input.split( / \, \s* / ).map: { .Int };
+ my Int $got = find-third-highest( @array );
+
+ is $got, $expected.Int, $test-name;
+ }
+
+ done-testing;
+}
+
+#------------------------------------------------------------------------------
+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, 4 | 3
+ Example 2| 5, 6 | 6
+ Example 3| 5, 4, 4, 3 | 3
+ Negatives|-1,-2,-3,-4,-2|-3
+ END
+}
+
+###############################################################################
diff --git a/challenge-205/athanasius/raku/ch-2.raku b/challenge-205/athanasius/raku/ch-2.raku
new file mode 100644
index 0000000000..155d804e4f
--- /dev/null
+++ b/challenge-205/athanasius/raku/ch-2.raku
@@ -0,0 +1,200 @@
+use v6d;
+
+###############################################################################
+=begin comment
+
+Perl Weekly Challenge 205
+=========================
+
+TASK #2
+-------
+*Maximum XOR*
+
+Submitted by: Mohammad S Anwar
+
+You are given an array of integers.
+
+Write a script to find the highest value obtained by XORing any two distinct
+members of the array.
+
+Example 1
+
+ Input: @array = (1,2,3,4,5,6,7)
+ Output: 7
+
+ The maximum result of 1 xor 6 = 7.
+
+Example 2
+
+ Input: @array = (2,4,1,3)
+ Output: 7
+
+ The maximum result of 4 xor 3 = 7.
+
+Example 3
+
+ Input: @array = (10,5,7,12,8)
+ Output: 15
+
+ The maximum result of 10 xor 5 = 15.
+
+=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 $VERBOSE is set to True, then the output is augmented with an explanation
+ of how the result was obtained.
+
+Assumption
+----------
+The elements of the input array are *non-negative* integers only, as shown in
+the examples.
+
+=end comment
+#==============================================================================
+
+use Test;
+
+my Bool constant $VERBOSE = True;
+
+#------------------------------------------------------------------------------
+BEGIN
+#------------------------------------------------------------------------------
+{
+ "\nChallenge 205, Task #2: Maximum XOR (Raku)\n".put;
+}
+
+#==============================================================================
+multi sub MAIN
+(
+ #| A list of non-negative integers, at least 2 distinct
+
+ *@array where { .elems >= 2 && .all ~~ UInt:D }
+)
+#==============================================================================
+{
+ "Input: \@array = (%s)\n".printf: @array.join: ',';
+
+ my UInt ($xor, $a, $b) = find-xor-max( @array );
+
+ "Output: $xor".put;
+
+ if $VERBOSE
+ {
+ my Str $bin-a = '%b'.sprintf: $a;
+ my Str $bin-b = '%b'.sprintf: $b;
+ my UInt $width = ($bin-a.chars, $bin-b.chars).max;
+
+ "\nThe maximum result of %*d xor %*d = %*d\n".printf:
+ $width, $a, $width, $b, $width, $xor;
+
+ " (binary: %0*b xor %0*b = %0*b)\n".printf:
+ $width, $a, $width, $b, $width, $xor;
+ }
+}
+
+#==============================================================================
+multi sub MAIN() # No input: run the test suite
+#==============================================================================
+{
+ run-tests();
+}
+
+#------------------------------------------------------------------------------
+sub find-xor-max( List:D[UInt:D] $array --> List:D[UInt:D] )
+#------------------------------------------------------------------------------
+{
+ my UInt %freq{UInt};
+
+ ++%freq{ $_ } for @$array;
+
+ my UInt @ordered = %freq.keys.sort;
+
+ @ordered.elems >= 2
+ or error( 'The input array does not contain 2 distinct members' );
+
+ my Int $xor-max = -1;
+ my UInt ($a-max, $b-max);
+
+ for 0 .. @ordered.end - 1 -> UInt $i
+ {
+ my UInt $a = @ordered[ $i ];
+
+ for $i + 1 .. @ordered.end -> UInt $j
+ {
+ my UInt $b = @ordered[ $j ];
+ my UInt $xor = $a +^ $b;
+
+ if $xor > $xor-max
+ {
+ $xor-max = $xor;
+ $a-max = $a;
+ $b-max = $b;
+ }
+ }
+ }
+
+ return $xor-max, $a-max, $b-max;
+}
+
+#------------------------------------------------------------------------------
+sub run-tests()
+#------------------------------------------------------------------------------
+{
+ 'Running the test suite'.put;
+
+ for test-data.lines -> Str $line
+ {
+ my Str ($test-name, $input, $expected) = $line.split: / \| /;
+
+ my UInt @array = $input.split( / \, \s* / ).map: { .Int };
+ my UInt $got = (find-xor-max( @array ))[ 0 ];
+
+ is $got, $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, 5, 6, 7|7
+ Example 2| 2, 4, 1, 3 |7
+ Example 3|10, 5, 7, 12, 8 |15
+ END
+}
+###############################################################################