aboutsummaryrefslogtreecommitdiff
path: root/challenge-269
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2024-05-16 11:01:14 +0100
committerGitHub <noreply@github.com>2024-05-16 11:01:14 +0100
commitd102ecbbd309745bdaec98cd5ef9bcbae5c9415b (patch)
tree27eddba27f3b38e0121d1798b6025a22dac4c6b1 /challenge-269
parent6e2fa7dbd4128b06645e20e01417b452ea3de250 (diff)
parentff10254ea1203eb543b2098bd9f1fc3f296de9cb (diff)
downloadperlweeklychallenge-club-d102ecbbd309745bdaec98cd5ef9bcbae5c9415b.tar.gz
perlweeklychallenge-club-d102ecbbd309745bdaec98cd5ef9bcbae5c9415b.tar.bz2
perlweeklychallenge-club-d102ecbbd309745bdaec98cd5ef9bcbae5c9415b.zip
Merge pull request #10101 from PerlMonk-Athanasius/branch-for-challenge-269
Perl & Raku solutions to Tasks 1 & 2 for Week 269
Diffstat (limited to 'challenge-269')
-rw-r--r--challenge-269/athanasius/perl/ch-1.pl226
-rw-r--r--challenge-269/athanasius/perl/ch-2.pl250
-rw-r--r--challenge-269/athanasius/raku/ch-1.raku214
-rw-r--r--challenge-269/athanasius/raku/ch-2.raku247
4 files changed, 937 insertions, 0 deletions
diff --git a/challenge-269/athanasius/perl/ch-1.pl b/challenge-269/athanasius/perl/ch-1.pl
new file mode 100644
index 0000000000..c30da1bd85
--- /dev/null
+++ b/challenge-269/athanasius/perl/ch-1.pl
@@ -0,0 +1,226 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 269
+=========================
+
+TASK #1
+-------
+*Bitwise OR*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of positive integers, @ints.
+
+Write a script to find out if it is possible to select two or more elements of
+the given array such that the bitwise OR of the selected elements has at least
+one trailing zero in its binary representation.
+
+Example 1
+
+ Input: @ints = (1, 2, 3, 4, 5)
+ Output: true
+
+ Say, we pick 2 and 4, their bitwise OR is 6. The binary representation of 6 is
+ 110. Return true since we have one trailing zero.
+
+Example 2
+
+ Input: @ints = (2, 3, 8, 16)
+ Output: true
+
+ Say, we pick 2 and 8, their bitwise OR is 10. The binary representation of 10
+ is 1010. Return true since we have one trailing zero.
+
+Example 3
+
+ Input: @ints = (1, 2, 5, 7, 9)
+ Output: false
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2024 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=comment
+
+Assumption
+----------
+The "positive" integers are the unsigned integers (which include zero).
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. A non-empty list of unsigned integers is entered on the command-line.
+3. If VERBOSE is set to a true value, the output gives the result (true or
+ false) followed by a brief explanation; otherwise, only the result is given.
+
+Algorithm
+---------
+For bitwise OR, 0 OR 0 = 0, 0 OR 1 = 1, 1 OR 0 = 1, and 1 OR 1 = 1. Therefore,
+the only way two binary operands will produce a zero as the least significant
+digit when OR-ed together is if both operands end in a zero.
+
+An unsigned integer's binary representation ends in a zero if and only if the
+integer is even (i.e., divisible by 2 without remainder).
+
+So, the algorithm is to search the input for even numbers. If two or more are
+found, a solution is possible and the result is true; otherwise, no solution is
+possible and the result is false.
+
+=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 => <<END;
+Usage:
+ perl $0 [<ints> ...]
+ perl $0
+
+ [<ints> ...] A non-empty list of unsigned integers
+END
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 269, Task #1: Bitwise OR (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] );
+ $_ >= 0 or error( "$_ is negative" );
+ }
+
+ printf "Input: \@ints = (%s)\n", join ', ', @ints;
+
+ my $result = test_bitwise_OR( \@ints );
+
+ printf "Output: %s\n", defined $result ? 'true' : 'false';
+
+ explain_result( $result ) if $VERBOSE;
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub test_bitwise_OR
+#-------------------------------------------------------------------------------
+{
+ my ($ints) = @_;
+ my ($result, $first);
+
+ for my $n (sort { $a <=> $b } @$ints)
+ {
+ if ($n % 2 == 0)
+ {
+ if (defined $first)
+ {
+ $result = [ $first, $n ];
+ last;
+ }
+ else
+ {
+ $first = $n;
+ }
+ }
+ }
+
+ return $result;
+}
+
+#-------------------------------------------------------------------------------
+sub explain_result
+#-------------------------------------------------------------------------------
+{
+ my ($result) = @_;
+
+ if (defined $result)
+ {
+ my $i = $result->[ 0 ];
+ my $j = $result->[ 1 ];
+ my $width = length sprintf '%b', $j;
+
+ printf "\n(%d, %d) is a solution because (%0*b OR %b) = %b\n",
+ $i, $j, $width, $i, $j, $i | $j;
+ }
+ else
+ {
+ print "\nThere are no solutions\n";
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub run_tests
+#-------------------------------------------------------------------------------
+{
+ print "Running the test suite\n";
+
+ while (my $line = <DATA>)
+ {
+ chomp $line;
+
+ my ($test, $ints_str, $exp_str, $exp1, $exp2) = split / \| /x, $line;
+
+ for ($test, $ints_str, $exp_str, $exp1, $exp2)
+ {
+ s/ ^ \s+ //x;
+ s/ \s+ $ //x;
+ }
+
+ my @ints = split / \s+ /x, $ints_str;
+ my $result = test_bitwise_OR( \@ints );
+ my $exp = $exp_str eq 'true';
+
+ is defined $result, $exp, "$test: Bool";
+
+ if (defined $result)
+ {
+ is $result->[ 0 ], $exp1, "$test: Op 1";
+ is $result->[ 1 ], $exp2, "$test: Op 2";
+ }
+ }
+
+ done_testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+################################################################################
+
+__DATA__
+Example 1| 1 2 3 4 5|true |2|4
+Example 2| 2 3 8 16 |true |2|8
+Example 3| 1 2 5 7 9|false| |
+Singleton|42 |false| |
diff --git a/challenge-269/athanasius/perl/ch-2.pl b/challenge-269/athanasius/perl/ch-2.pl
new file mode 100644
index 0000000000..0bc87b11bd
--- /dev/null
+++ b/challenge-269/athanasius/perl/ch-2.pl
@@ -0,0 +1,250 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 269
+=========================
+
+TASK #2
+-------
+*Distribute Elements*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of distinct integers, @ints.
+
+Write a script to distribute the elements as described below:
+
+ 1) Put the 1st element of the given array to a new array @arr1.
+ 2) Put the 2nd element of the given array to a new array @arr2.
+
+Once you have one element in each arrays, @arr1 and @arr2, then follow the rule
+below:
+
+ If the last element of the array @arr1 is greater than the last
+ element of the array @arr2 then add the first element of the
+ given array to @arr1 otherwise to the array @arr2.
+
+When done distribution, return the concatenated arrays. @arr1 and @arr2.
+
+Example 1
+
+ Input: @ints = (2, 1, 3, 4, 5)
+ Output: (2, 3, 4, 5, 1)
+
+ 1st operation:
+ Add 1 to @arr1 = (2)
+
+ 2nd operation:
+ Add 2 to @arr2 = (1)
+
+ 3rd operation:
+ Now the last element of @arr1 is greater than the last element
+ of @arr2, add 3 to @arr1 = (2, 3).
+
+ 4th operation:
+ Again the last element of @arr1 is greate than the last element
+ of @arr2, add 4 to @arr1 = (2, 3, 4)
+
+ 5th operation:
+ Finally, the last element of @arr1 is again greater than the last
+ element of @arr2, add 5 to @arr1 = (2, 3, 4, 5)
+
+ Mow we have two arrays:
+ @arr1 = (2, 3, 4, 5)
+ @arr2 = (1)
+
+ Concatenate the two arrays and return the final array: (2, 3, 4, 5, 1).
+
+Example 2
+
+ Input: @ints = (3, 2, 4)
+ Output: (3, 4, 2)
+
+ 1st operation:
+ Add 1 to @arr1 = (3)
+
+ 2nd operation:
+ Add 2 to @arr2 = (2)
+
+ 3rd operation:
+ Now the last element of @arr1 is greater than the last element
+ of @arr2, add 4 to @arr1 = (3, 4).
+
+ Now we have two arrays:
+ @arr1 = (3, 4)
+ @arr2 = (2)
+
+ Concatenate the two arrays and return the final array: (3, 4, 2).
+
+Example 3
+
+ Input: @ints = (5, 4, 3, 8)
+ Output: (5, 3, 4, 8)
+
+ 1st operation:
+ Add 1 to @arr1 = (5)
+
+ 2nd operation:
+ Add 2 to @arr2 = (4)
+
+ 3rd operation:
+ Now the last element of @arr1 is greater than the last element
+ of @arr2, add 3 to @arr1 = (5, 3).
+
+ 4th operation:
+ Again the last element of @arr2 is greate than the last element
+ of @arr1, add 8 to @arr2 = (4, 8)
+
+ Now we have two arrays:
+ @arr1 = (5, 3)
+ @arr2 = (4, 8)
+
+ Concatenate the two arrays and return the final array: (5, 3, 4, 8).
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2024 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=comment
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. The input integers are entered on the command-line.
+
+=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 distinct integers
+END
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 269, Task #2: Distribute Elements (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ if (scalar @ARGV == 0)
+ {
+ run_tests();
+ }
+ else
+ {
+ my @ints = @ARGV;
+
+ check_input( \@ints );
+
+ printf "Input: \@ints = (%s)\n", join ', ', @ints;
+
+ my $soln = distribute_elements( \@ints );
+
+ printf "Output: (%s)\n", join ', ', @$soln;
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub distribute_elements
+#-------------------------------------------------------------------------------
+{
+ my ($ints) = @_;
+ my @arr1 = shift @$ints;
+ my @arr2 = shift @$ints if @$ints;
+
+ while (@$ints)
+ {
+ my $target = $arr1[ -1 ] > $arr2[ -1 ] ? \@arr1 : \@arr2;
+
+ push @$target, shift @$ints;
+ }
+
+ push @arr1, @arr2;
+
+ return \@arr1;
+}
+
+#-------------------------------------------------------------------------------
+sub check_input
+#-------------------------------------------------------------------------------
+{
+ my ($ints) = @_;
+ my %dict;
+
+ for (@$ints)
+ {
+ / ^ $RE{num}{int} $ /x or error( qq["$_" is not a valid integer] );
+
+ ++$dict{ $_ } == 1 or error( 'Duplicate found' );
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub run_tests
+#-------------------------------------------------------------------------------
+{
+ print "Running the test suite\n";
+
+ while (my $line = <DATA>)
+ {
+ chomp $line;
+
+ my ($test_name, $ints_str, $expd_str) = split / \| /x, $line;
+
+ for ($test_name, $ints_str, $expd_str)
+ {
+ s/ ^ \s+ //x;
+ s/ \s+ $ //x;
+ }
+
+ my @ints = split / \s+ /x, $ints_str;
+
+ check_input( \@ints );
+
+ my $soln = distribute_elements( \@ints );
+ my @expd = split / \s+ /x, $expd_str;
+
+ is_deeply $soln, \@expd, $test_name;
+ }
+
+ done_testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+################################################################################
+
+__DATA__
+Example 1| 2 1 3 4 5| 2 3 4 5 1
+Example 2| 3 2 4 | 3 4 2
+Example 3| 5 4 3 8 | 5 3 4 8
+Singleton|17 |17
+Negatives|-1 1 -2 2 |-1 2 1 -2
diff --git a/challenge-269/athanasius/raku/ch-1.raku b/challenge-269/athanasius/raku/ch-1.raku
new file mode 100644
index 0000000000..332122f587
--- /dev/null
+++ b/challenge-269/athanasius/raku/ch-1.raku
@@ -0,0 +1,214 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 269
+=========================
+
+TASK #1
+-------
+*Bitwise OR*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of positive integers, @ints.
+
+Write a script to find out if it is possible to select two or more elements of
+the given array such that the bitwise OR of the selected elements has at least
+one trailing zero in its binary representation.
+
+Example 1
+
+ Input: @ints = (1, 2, 3, 4, 5)
+ Output: true
+
+ Say, we pick 2 and 4, their bitwise OR is 6. The binary representation of 6 is
+ 110. Return true since we have one trailing zero.
+
+Example 2
+
+ Input: @ints = (2, 3, 8, 16)
+ Output: true
+
+ Say, we pick 2 and 8, their bitwise OR is 10. The binary representation of 10
+ is 1010. Return true since we have one trailing zero.
+
+Example 3
+
+ Input: @ints = (1, 2, 5, 7, 9)
+ Output: false
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2024 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=begin comment
+
+Assumption
+----------
+The "positive" integers are the unsigned integers (which include zero).
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. A non-empty list of unsigned integers is entered on the command-line.
+3. If VERBOSE is set to True, the output gives the result (true or false)
+ followed by a brief explanation; otherwise, only the result is given.
+
+Algorithm
+---------
+For bitwise OR, 0 OR 0 = 0, 0 OR 1 = 1, 1 OR 0 = 1, and 1 OR 1 = 1. Therefore,
+the only way two binary operands will produce a zero as the least significant
+digit when OR-ed together is if both operands end in a zero.
+
+An unsigned integer's binary representation ends in a zero if and only if the
+integer is even (i.e., divisible by 2 without remainder).
+
+So, the algorithm is to search the input for even numbers. If two or more are
+found, a solution is possible and the result is true; otherwise, no solution is
+possible and the result is false.
+
+=end comment
+#===============================================================================
+
+use Test;
+
+my Bool constant VERBOSE = True;
+
+subset Result of List where (UInt, UInt);
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 269, Task #1: Bitwise OR (Raku)\n".put;
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ #| A non-empty list of unsigned integers
+
+ *@ints where { .elems > 0 && .all ~~ UInt:D }
+)
+#===============================================================================
+{
+ "Input: \@ints = (%s)\n".printf: @ints.join: ', ';
+
+ my Result $result = test-bitwise-OR( @ints );
+
+ "Output: %s\n".printf: $result.defined ?? 'true' !! 'false';
+
+ if VERBOSE
+ {
+ if $result.defined
+ {
+ my UInt $i = $result[ 0 ];
+ my UInt $j = $result[ 1 ];
+ my UInt $width = '%b'.sprintf( $j ).chars;
+
+ "\n(%d, %d) is a solution because (%0*b OR %b) = %b\n".printf:
+ $i, $j, $width, $i, $j, $i +| $j;
+ }
+ else
+ {
+ "\nThere are no solutions".put;
+ }
+ }
+}
+
+#===============================================================================
+multi sub MAIN() # No input: run the test suite
+#===============================================================================
+{
+ run-tests();
+}
+
+#-------------------------------------------------------------------------------
+sub test-bitwise-OR( List:D[UInt:D] $ints --> Result )
+#-------------------------------------------------------------------------------
+{
+ my Result $result;
+ my UInt $first;
+
+ for $ints.sort -> UInt $n
+ {
+ if $n %% 2
+ {
+ if $first.defined
+ {
+ $result = [$first, $n];
+ last;
+ }
+ else
+ {
+ $first = $n;
+ }
+ }
+ }
+
+ return $result;
+}
+
+#-------------------------------------------------------------------------------
+sub run-tests()
+#-------------------------------------------------------------------------------
+{
+ 'Running the test suite'.put;
+
+ for test-data.lines -> Str $line
+ {
+ my Str ($test, $ints-str, $exp-str, $exp1, $exp2) = $line.split: / \| /;
+
+ for $test, $ints-str, $exp-str, $exp1, $exp2
+ {
+ s/ ^ \s+ //;
+ s/ \s+ $ //;
+ }
+
+ my UInt @ints = $ints-str.split( / \s+ /, :skip-empty )
+ .map: { .Int };
+ my Result $result = test-bitwise-OR( @ints );
+ my Bool $expected = $exp-str eq 'true';
+
+ is $result.defined, $expected, "$test: Bool";
+
+ if $result.defined
+ {
+ is $result[ 0 ], $exp1.Int, "$test: Op 1";
+ is $result[ 1 ], $exp2.Int, "$test: Op 2";
+ }
+ }
+
+ 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| 1 2 3 4 5|true |2|4
+ Example 2| 2 3 8 16 |true |2|8
+ Example 3| 1 2 5 7 9|false| |
+ Singleton|42 |false| |
+ END
+}
+
+################################################################################
diff --git a/challenge-269/athanasius/raku/ch-2.raku b/challenge-269/athanasius/raku/ch-2.raku
new file mode 100644
index 0000000000..71e97f491e
--- /dev/null
+++ b/challenge-269/athanasius/raku/ch-2.raku
@@ -0,0 +1,247 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 269
+=========================
+
+TASK #2
+-------
+*Distribute Elements*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of distinct integers, @ints.
+
+Write a script to distribute the elements as described below:
+
+ 1) Put the 1st element of the given array to a new array @arr1.
+ 2) Put the 2nd element of the given array to a new array @arr2.
+
+Once you have one element in each arrays, @arr1 and @arr2, then follow the rule
+below:
+
+ If the last element of the array @arr1 is greater than the last
+ element of the array @arr2 then add the first element of the
+ given array to @arr1 otherwise to the array @arr2.
+
+When done distribution, return the concatenated arrays. @arr1 and @arr2.
+
+Example 1
+
+ Input: @ints = (2, 1, 3, 4, 5)
+ Output: (2, 3, 4, 5, 1)
+
+ 1st operation:
+ Add 1 to @arr1 = (2)
+
+ 2nd operation:
+ Add 2 to @arr2 = (1)
+
+ 3rd operation:
+ Now the last element of @arr1 is greater than the last element
+ of @arr2, add 3 to @arr1 = (2, 3).
+
+ 4th operation:
+ Again the last element of @arr1 is greate than the last element
+ of @arr2, add 4 to @arr1 = (2, 3, 4)
+
+ 5th operation:
+ Finally, the last element of @arr1 is again greater than the last
+ element of @arr2, add 5 to @arr1 = (2, 3, 4, 5)
+
+ Mow we have two arrays:
+ @arr1 = (2, 3, 4, 5)
+ @arr2 = (1)
+
+ Concatenate the two arrays and return the final array: (2, 3, 4, 5, 1).
+
+Example 2
+
+ Input: @ints = (3, 2, 4)
+ Output: (3, 4, 2)
+
+ 1st operation:
+ Add 1 to @arr1 = (3)
+
+ 2nd operation:
+ Add 2 to @arr2 = (2)
+
+ 3rd operation:
+ Now the last element of @arr1 is greater than the last element
+ of @arr2, add 4 to @arr1 = (3, 4).
+
+ Now we have two arrays:
+ @arr1 = (3, 4)
+ @arr2 = (2)
+
+ Concatenate the two arrays and return the final array: (3, 4, 2).
+
+Example 3
+
+ Input: @ints = (5, 4, 3, 8)
+ Output: (5, 3, 4, 8)
+
+ 1st operation:
+ Add 1 to @arr1 = (5)
+
+ 2nd operation:
+ Add 2 to @arr2 = (4)
+
+ 3rd operation:
+ Now the last element of @arr1 is greater than the last element
+ of @arr2, add 3 to @arr1 = (5, 3).
+
+ 4th operation:
+ Again the last element of @arr2 is greate than the last element
+ of @arr1, add 8 to @arr2 = (4, 8)
+
+ Now we have two arrays:
+ @arr1 = (5, 3)
+ @arr2 = (4, 8)
+
+ Concatenate the two arrays and return the final array: (5, 3, 4, 8).
+
+=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 input integers are entered 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.
+
+=end comment
+#===============================================================================
+
+use Test;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 269, Task #2: Distribute Elements (Raku)\n".put;
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ #| A non-empty list of distinct integers
+
+ *@ints where { .elems > 0 && .all ~~ Int:D && are-distinct( @ints ) }
+)
+#===============================================================================
+{
+ "Input: \@ints = (%s)\n".printf: @ints.join: ', ';
+
+ my Int @soln = distribute-elements( @ints );
+
+ "Output: (%s)\n"\.printf: @soln.join: ', ';
+}
+
+#===============================================================================
+multi sub MAIN() # No input: run the test suite
+#===============================================================================
+{
+ run-tests();
+}
+
+#-------------------------------------------------------------------------------
+sub distribute-elements
+(
+ List:D[Int:D] $ints where { .elems > 0 && are-distinct( $ints ) }
+--> List:D[Int:D]
+)
+#-------------------------------------------------------------------------------
+{
+ my Int @ints = @$ints; # Make a copy
+ my Int @arr1 = @ints.shift;
+ my Int @arr2 = @ints.shift if @ints;
+
+ while @ints
+ {
+ my Int @target := @arr1[ *-1 ] > @arr2[ *-1 ] ?? @arr1 !! @arr2;
+
+ @target.push: @ints.shift;
+ }
+
+ return @arr1.append: @arr2;
+}
+
+#-------------------------------------------------------------------------------
+sub are-distinct( List:D[Int:D] $ints --> Bool:D )
+#-------------------------------------------------------------------------------
+{
+ my UInt %dict{Int};
+
+ for @$ints
+ {
+ return False if ++%dict{ $_ } > 1;
+ }
+
+ return True;
+}
+
+#-------------------------------------------------------------------------------
+sub run-tests()
+#-------------------------------------------------------------------------------
+{
+ 'Running the test suite'.put;
+
+ for test-data.lines -> Str $line
+ {
+ my Str ($test-name, $ints-str, $expd-str) = $line.split: / \| /;
+
+ for $test-name, $ints-str, $expd-str
+ {
+ s/ ^ \s+ //;
+ s/ \s+ $ //;
+ }
+
+ my Int @ints = $ints-str.split( / \s+ /, :skip-empty ).map: { .Int };
+
+ are-distinct( @ints );
+
+ my Int @soln = distribute-elements( @ints );
+ my Int @expd = $expd-str.split( / \s+ /, :skip-empty ).map: { .Int };
+
+ is-deeply @soln, @expd, $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| 2 1 3 4 5| 2 3 4 5 1
+ Example 2| 3 2 4 | 3 4 2
+ Example 3| 5 4 3 8 | 5 3 4 8
+ Singleton|17 |17
+ Negatives|-1 1 -2 2 |-1 2 1 -2
+ END
+}
+
+################################################################################