aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-208/athanasius/perl/ch-1.pl213
-rw-r--r--challenge-208/athanasius/perl/ch-2.pl278
-rw-r--r--challenge-208/athanasius/raku/ch-1.raku220
-rw-r--r--challenge-208/athanasius/raku/ch-2.raku282
4 files changed, 993 insertions, 0 deletions
diff --git a/challenge-208/athanasius/perl/ch-1.pl b/challenge-208/athanasius/perl/ch-1.pl
new file mode 100644
index 0000000000..41d55bef1b
--- /dev/null
+++ b/challenge-208/athanasius/perl/ch-1.pl
@@ -0,0 +1,213 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 208
+=========================
+
+TASK #1
+-------
+*Minimum Index Sum*
+
+Submitted by: Mohammad S Anwar
+
+You are given two arrays of strings.
+
+Write a script to find out all common strings in the given two arrays with
+minimum index sum. If no common strings found returns an empty list.
+
+Example 1
+
+ Input: @list1 = ("Perl", "Raku", "Love")
+ @list2 = ("Raku", "Perl", "Hate")
+
+ Output: ("Perl", "Raku")
+
+ There are two common strings "Perl" and "Raku".
+ Index sum of "Perl": 0 + 1 = 1
+ Index sum of "Raku": 1 + 0 = 1
+
+Example 2
+
+ Input: @list1 = ("A", "B", "C")
+ @list2 = ("D", "E", "F")
+
+ Output: ()
+
+ No common string found, so no result.
+
+Example 3
+
+ Input: @list1 = ("A", "B", "C")
+ @list2 = ("C", "A", "B")
+
+ Output: ("A")
+
+ There are three common strings "A", "B" and "C".
+ Index sum of "A": 0 + 1 = 1
+ Index sum of "B": 1 + 2 = 3
+ Index sum of "C": 2 + 0 = 2
+
+=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 List::Util qw( min );
+use Test::More;
+
+const my $SEPARATOR => '-';
+const my $USAGE =>
+"Usage:
+ perl $0 [<list> ...]
+ perl $0
+
+ [<list> ...] <string list 1> - <string list 2>\n";
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 208, Task #1: Minimum Index Sum (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ my $args = scalar @ARGV;
+
+ if ($args == 0)
+ {
+ run_tests();
+ }
+ else
+ {
+ my ($list1, $list2) = parse_command_line( @ARGV );
+
+ printf "Input: \@list1 = (%s)\n", format_list( $list1 );
+ printf " \@list2 = (%s)\n", format_list( $list2 );
+
+ my $strings = find_min_idx_strings( $list1, $list2 );
+
+ printf "\nOutput: (%s)\n", format_list( $strings );
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub find_min_idx_strings
+#-------------------------------------------------------------------------------
+{
+ my ($list1, $list2) = @_;
+ my %common;
+
+ OUTER:
+ for my $i (0 .. $#$list1)
+ {
+ my $elem1 = $list1->[ $i ];
+
+ for my $j (0 .. $#$list2)
+ {
+ my $elem2 = $list2->[ $j ];
+
+ if ($elem1 eq $elem2)
+ {
+ push @{ $common{ $i + $j } }, $elem1;
+ next OUTER;
+ }
+ }
+ }
+
+ my $min_idx = min keys %common;
+
+ return defined $min_idx ? $common{ $min_idx } : [];
+}
+
+#-------------------------------------------------------------------------------
+sub parse_command_line
+#-------------------------------------------------------------------------------
+{
+ my @args = @_;
+ my $idx = -1;
+
+ for my $i (0 .. $#args)
+ {
+ if ($args[ $i ] eq $SEPARATOR)
+ {
+ $idx = $i;
+ last;
+ }
+ }
+
+ $idx >= 0 or error( qq[Missing list separator "$SEPARATOR"] );
+
+ return ([ @args[ 0 .. $idx - 1 ] ],
+ [ @args[ $idx + 1 .. $#args ] ]);
+}
+
+#-------------------------------------------------------------------------------
+sub format_list
+#-------------------------------------------------------------------------------
+{
+ my ($list) = @_;
+
+ return join ', ', map { qq["$_"] } @$list;
+}
+
+#-------------------------------------------------------------------------------
+sub run_tests
+#-------------------------------------------------------------------------------
+{
+ print "Running the test suite\n";
+
+ while (my $line = <DATA>)
+ {
+ chomp $line;
+
+ my ($test_name, $input, $expected) = split / \| /x, $line;
+
+ $test_name =~ s/ \s+ $ //x;
+
+ my @args = split / \s+ /x, $input;
+ my ($list1, $list2) = parse_command_line( @args );
+ my $strings = find_min_idx_strings( $list1, $list2 );
+ my $got = join ' ', @$strings;
+
+ is $got, $expected, $test_name;
+ }
+
+ done_testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+################################################################################
+
+__DATA__
+Example 1|Perl Raku Love - Raku Perl Hate|Perl Raku
+Example 2|A B C - D E F |
+Example 3|A B C - C A B |A
diff --git a/challenge-208/athanasius/perl/ch-2.pl b/challenge-208/athanasius/perl/ch-2.pl
new file mode 100644
index 0000000000..1c685f02d7
--- /dev/null
+++ b/challenge-208/athanasius/perl/ch-2.pl
@@ -0,0 +1,278 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 208
+=========================
+
+TASK #2
+-------
+*Duplicate and Missing*
+
+Submitted by: Mohammad S Anwar
+
+You are given an array of integers in sequence with one missing and one dupli-
+cate.
+
+Write a script to find the duplicate and missing integer in the given array.
+Return -1 if none found.
+
+For the sake of this task, let us assume the array contains no more than one
+duplicate and missing.
+
+Example 1:
+
+ Input: @nums = (1,2,2,4)
+ Output: (2,3)
+
+ Duplicate is 2 and Missing is 3.
+
+Example 2:
+
+ Input: @nums = (1,2,3,4)
+ Output: -1
+
+ No duplicate and missing found.
+
+Example 3:
+
+ Input: @nums = (1,2,3,3)
+ Output: (3,4)
+
+ Duplicate is 3 and Missing is 4.
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2023 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=comment
+
+Interface
+---------
+If no command-line arguments are given, the test suite is run.
+
+Error Handling
+--------------
+1. Input errors abort the script with a Usage message. The following are input
+ errors:
+ - an element in the input array is not a valid integer
+ - the input array is not sorted in monotonically increasing order.
+
+2. Sequence errors produce an output of "-1". If $VERBOSE is set to a true
+ value, an error message is also printed (immediately before the output). The
+ following are sequence errors:
+ - an element is duplicated more than once
+ - more than one element is duplicated
+ - there is a gap in the sequence of more than one integer
+ - there is more than one gap in the sequence.
+
+ If no duplicates are found, this is not an error, but since the output is -1,
+ an explanatory note is printed if $VERBOSE is true.
+
+=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 <nums>
+ perl $0
+
+ <nums> An ordered list of integers\n";
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 208, Task #2: Duplicate and Missing (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ if (scalar @ARGV == 0)
+ {
+ run_tests();
+ }
+ else
+ {
+ my $nums = parse_command_line();
+
+ printf "Input: \@nums = (%s)\n", join ',', @$nums;
+
+ my ($dups, $elem) = find_duplicates( $nums );
+ my $output = -1;
+
+ if ($dups > 0)
+ {
+ my $missing = find_missing( $nums );
+ $output = defined $missing ? "($elem,$missing)" : -1;
+ }
+ elsif ($VERBOSE)
+ {
+ warn "Note: No duplicate found\n";
+ }
+
+ print "Output: $output\n";
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub find_duplicates
+#-------------------------------------------------------------------------------
+{
+ my ($nums) = @_;
+ my (%counts, @dups);
+
+ ++$counts{ $_ } for @$nums;
+
+ for my $num (sort keys %counts)
+ {
+ my $count = $counts{ $num };
+
+ if ($count > 2)
+ {
+ seq_error( qq["$num" is duplicated more than once] );
+ return;
+ }
+ elsif ($count == 2)
+ {
+ push @dups, $num;
+ }
+ }
+
+ my $dups = scalar @dups;
+
+ if ($dups > 1)
+ {
+ seq_error( 'More than one integer is duplicated' );
+ return;
+ }
+
+ return ($dups, $dups == 0 ? '' : $dups[ 0 ]);
+}
+
+#-------------------------------------------------------------------------------
+sub find_missing
+#-------------------------------------------------------------------------------
+{
+ my ($nums) = @_;
+ my $elem = $nums->[ 0 ];
+ my $count = 0;
+ my $missing;
+
+ for my $i (1 .. $#$nums)
+ {
+ my $next = $nums->[ $i ];
+ my $diff = $next - $elem;
+
+ if ($diff > 2)
+ {
+ seq_error( "More than one integer is missing between $elem and " .
+ "and $next" );
+ return;
+ }
+ elsif ($diff == 2)
+ {
+ $missing = $elem + 1;
+ ++$count;
+ }
+
+ $elem = $next;
+ }
+
+ if ($count > 1)
+ {
+ seq_error( 'There is more than one gap in the sequence' );
+ return;
+ }
+
+ return $missing // $nums->[ -1 ] + 1;
+}
+
+#-------------------------------------------------------------------------------
+sub parse_command_line
+#-------------------------------------------------------------------------------
+{
+ my $elem = $ARGV[ 0 ];
+ $elem =~ / ^ $RE{num}{int} $ /x
+ or input_error( qq["$elem" is not a valid integer] );
+
+ for my $i (1 .. $#ARGV)
+ {
+ my $next = $ARGV[ $i ];
+ $next =~ / ^ $RE{num}{int} $ /x
+ or input_error( qq["$next" is not a valid integer] );
+
+ $elem <= $next or input_error( 'The input array is not in sequence' );
+ $elem = $next;
+ }
+
+ 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 @nums = split / \, /x, $input;
+ my ($dups, $elem) = find_duplicates( \@nums );
+ my $got = -1;
+
+ if ($dups)
+ {
+ my $missing = find_missing( \@nums );
+ $got = "$elem,$missing";
+ }
+
+ is $got, $expected, $test_name;
+ }
+
+ done_testing;
+}
+
+#-------------------------------------------------------------------------------
+sub input_error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+#-------------------------------------------------------------------------------
+sub seq_error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ warn "Error: $message\n" if $VERBOSE;
+}
+
+################################################################################
+
+__DATA__
+Example 1|1,2,2,4|2,3
+Example 2|1,2,3,4|-1
+Example 3|1,2,3,3|3,4
diff --git a/challenge-208/athanasius/raku/ch-1.raku b/challenge-208/athanasius/raku/ch-1.raku
new file mode 100644
index 0000000000..525b6d2087
--- /dev/null
+++ b/challenge-208/athanasius/raku/ch-1.raku
@@ -0,0 +1,220 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 208
+=========================
+
+TASK #1
+-------
+*Minimum Index Sum*
+
+Submitted by: Mohammad S Anwar
+
+You are given two arrays of strings.
+
+Write a script to find out all common strings in the given two arrays with
+minimum index sum. If no common strings found returns an empty list.
+
+Example 1
+
+ Input: @list1 = ("Perl", "Raku", "Love")
+ @list2 = ("Raku", "Perl", "Hate")
+
+ Output: ("Perl", "Raku")
+
+ There are two common strings "Perl" and "Raku".
+ Index sum of "Perl": 0 + 1 = 1
+ Index sum of "Raku": 1 + 0 = 1
+
+Example 2
+
+ Input: @list1 = ("A", "B", "C")
+ @list2 = ("D", "E", "F")
+
+ Output: ()
+
+ No common string found, so no result.
+
+Example 3
+
+ Input: @list1 = ("A", "B", "C")
+ @list2 = ("C", "A", "B")
+
+ Output: ("A")
+
+ There are three common strings "A", "B" and "C".
+ Index sum of "A": 0 + 1 = 1
+ Index sum of "B": 1 + 2 = 3
+ Index sum of "C": 2 + 0 = 2
+
+=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;
+
+my Str constant $SEPARATOR = '-';
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 208, Task #1: Minimum Index Sum (Raku)\n".put;
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ *@list #= <string list 1> - <string list 2>
+)
+#===============================================================================
+{
+ my List @lists = parse-command-line( @list );
+
+ "Input: \@list1 = (%s)\n".printf: format-list( @lists[ 0 ] );
+ " \@list2 = (%s)\n".printf: format-list( @lists[ 1 ] );
+
+ my Str @strings = |find-min-idx-strings( @lists );
+
+ "\nOutput: (%s)\n".printf: format-list( @strings );
+}
+
+#===============================================================================
+multi sub MAIN() # No input: run the test suite
+#===============================================================================
+{
+ run-tests();
+}
+
+#-------------------------------------------------------------------------------
+sub find-min-idx-strings( List:D[List:D[Str:D]] $lists --> List:D[Str:D] )
+#-------------------------------------------------------------------------------
+{
+ my Array[Str] %common{ UInt };
+
+ L-OUTER:
+ for 0 .. $lists[ 0 ].end -> UInt $i
+ {
+ my Str $elem1 = $lists[ 0; $i ];
+
+ for 0 .. $lists[ 1 ].end -> UInt $j
+ {
+ my Str $elem2 = $lists[ 1; $j ];
+
+ if $elem1 eq $elem2
+ {
+ %common{ $i + $j }.push: $elem1;
+ next L-OUTER;
+ }
+ }
+ }
+
+ return [] if %common.elems == 0;
+
+ my UInt $min-idx = %common.keys.min;
+
+ return %common{ $min-idx };
+}
+
+#-------------------------------------------------------------------------------
+sub parse-command-line
+(
+ List:D[Str:D] $list --> List:D[ List:D[Str:D], List:D[Str:D] ]
+)
+#-------------------------------------------------------------------------------
+{
+ my Int $idx = -1;
+
+ for 0 .. $list.end -> UInt $i
+ {
+ if $list[ $i ] eq $SEPARATOR
+ {
+ $idx = $i;
+ last;
+ }
+ }
+
+ $idx >= 0 or error( qq[Missing list separator "$SEPARATOR"] );
+
+ return $list[ 0 .. $idx - 1 ], $list[ $idx + 1 .. $list.end ];
+}
+
+#-------------------------------------------------------------------------------
+sub format-list( List:D[Str:D] $list --> Str:D )
+#-------------------------------------------------------------------------------
+{
+ return $list.map( { qq["$_"] } ).join: ', ';
+}
+
+#-------------------------------------------------------------------------------
+sub run-tests()
+#-------------------------------------------------------------------------------
+{
+ 'Running the test suite'.put;
+
+ for test-data.lines -> Str $line
+ {
+ my Str ($test-name, $input, $expected) = $line.split: / \| /;
+
+ $test-name ~~ s/ \s+ $ //;
+
+ my Str @args = $input.split: / \s+ /;
+ my List @lists = parse-command-line( @args );
+ my Str @strings = |find-min-idx-strings( @lists );
+ my Str $got = @strings.join: ' ';
+
+ is $got, $expected, $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|Perl Raku Love - Raku Perl Hate|Perl Raku
+ Example 2|A B C - D E F |
+ Example 3|A B C - C A B |A
+ END
+}
+
+################################################################################
diff --git a/challenge-208/athanasius/raku/ch-2.raku b/challenge-208/athanasius/raku/ch-2.raku
new file mode 100644
index 0000000000..071a0b6795
--- /dev/null
+++ b/challenge-208/athanasius/raku/ch-2.raku
@@ -0,0 +1,282 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 208
+=========================
+
+TASK #2
+-------
+*Duplicate and Missing*
+
+Submitted by: Mohammad S Anwar
+
+You are given an array of integers in sequence with one missing and one dupli-
+cate.
+
+Write a script to find the duplicate and missing integer in the given array.
+Return -1 if none found.
+
+For the sake of this task, let us assume the array contains no more than one
+duplicate and missing.
+
+Example 1:
+
+ Input: @nums = (1,2,2,4)
+ Output: (2,3)
+
+ Duplicate is 2 and Missing is 3.
+
+Example 2:
+
+ Input: @nums = (1,2,3,4)
+ Output: -1
+
+ No duplicate and missing found.
+
+Example 3:
+
+ Input: @nums = (1,2,3,3)
+ Output: (3,4)
+
+ Duplicate is 3 and Missing is 4.
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2023 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=begin comment
+
+Interface
+---------
+If no command-line arguments are given, the test suite is run.
+
+Error Handling
+--------------
+1. Input errors abort the script with a Usage message. The following are input
+ errors:
+ - an element in the input array is not a valid integer
+ - the input array is not sorted in monotonically increasing order.
+
+2. Sequence errors produce an output of "-1". If $VERBOSE is set to True, an
+ error message is also printed (immediately before the output). The following
+ are sequence errors:
+ - an element is duplicated more than once
+ - more than one element is duplicated
+ - there is a gap in the sequence of more than one integer
+ - there is more than one gap in the sequence.
+
+ If no duplicates are found, this is not an error, but since the output is -1,
+ an explanatory note is printed if $VERBOSE is True.
+
+=end comment
+#===============================================================================
+
+use Test;
+
+my Bool constant $VERBOSE = True;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 208, Task #2: Duplicate and Missing (Raku)\n".put;
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ #| An ordered list of integers
+
+ *@nums where { .elems > 0 && .all ~~ Int:D && is-ordered( @nums ) }
+)
+#===============================================================================
+{
+ "Input: \@nums = (%s)\n".printf: @nums.join: ',';
+
+ my (UInt $dups,
+ Int $elem) = find-duplicates( @nums );
+ my Str $output = '-1';
+
+ if $dups > 0
+ {
+ my Int $missing = find-missing( @nums );
+ $output = $missing.defined ?? "($elem,$missing)" !! '-1';
+ }
+ elsif $VERBOSE
+ {
+ 'Note: No duplicate found'.note;
+ }
+
+ "Output: $output".put;
+}
+
+#===============================================================================
+multi sub MAIN() # No input: run the test suite
+#===============================================================================
+{
+ run-tests();
+}
+
+#-------------------------------------------------------------------------------
+sub find-duplicates( List:D[Int:D] $nums --> List:D[ UInt:D, Int ] )
+#-------------------------------------------------------------------------------
+{
+ my Int %counts{ UInt };
+ my Int @dups;
+
+ ++%counts{ $_ } for @$nums;
+
+ for %counts.keys.sort -> $num
+ {
+ my UInt $count = %counts{ $num };
+
+ if $count > 2
+ {
+ seq-error( qq["$num" is duplicated more than once] );
+ return;
+ }
+ elsif $count == 2
+ {
+ @dups.push: $num;
+ }
+ }
+
+ my UInt $dups = @dups.elems;
+
+ if $dups > 1
+ {
+ seq-error( 'More than one integer is duplicated' );
+ return;
+ }
+
+ return $dups, $dups == 0 ?? Int !! @dups[ 0 ];
+}
+
+#-------------------------------------------------------------------------------
+sub find-missing( List:D[Int:D] $nums --> Int )
+#-------------------------------------------------------------------------------
+{
+ my Int $elem = $nums[ 0 ];
+ my UInt $count = 0;
+ my Int $missing;
+
+ for 1 .. $nums.end -> UInt $i
+ {
+ my Int $next = $nums[ $i ];
+ my UInt $diff = $next - $elem;
+
+ if $diff > 2
+ {
+ seq-error( "More than one integer is missing between $elem and " ~
+ "and $next" );
+ return;
+ }
+ elsif $diff == 2
+ {
+ $missing = $elem + 1;
+ ++$count;
+ }
+
+ $elem = $next;
+ }
+
+ if $count > 1
+ {
+ seq-error( 'There is more than one gap in the sequence' );
+ return;
+ }
+
+ return $missing // $nums[ *-1 ] + 1;
+}
+
+#-------------------------------------------------------------------------------
+sub is-ordered( List:D[Int:D] $nums --> Bool:D )
+#-------------------------------------------------------------------------------
+{
+ my Int $elem = $nums[ 0 ];
+
+ for 1 .. $nums.end -> UInt $i
+ {
+ my Int $next = $nums[ $i ];
+
+ $elem <= $next or return False;
+ $elem = $next;
+ }
+
+ return True;
+}
+
+#-------------------------------------------------------------------------------
+sub run-tests()
+#-------------------------------------------------------------------------------
+{
+ 'Running the test suite'.put;
+
+ for test-data.lines -> Str $line
+ {
+ my Str ($test-name, $input, $expected) = $line.split: / \| /;
+
+ my Int @nums = $input.split( / \, / ).map: { .Int };
+ my (UInt $dups,
+ Int $elem) = find-duplicates( @nums );
+ my Str $got = '-1';
+
+ if $dups
+ {
+ my Int $missing = find-missing( @nums );
+ $got = "$elem,$missing";
+ }
+
+ is $got, $expected, $test-name;
+ }
+
+ done-testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error( Str:D $message )
+#-------------------------------------------------------------------------------
+{
+ "ERROR: $message".put;
+
+ USAGE();
+
+ exit 0;
+}
+
+#-------------------------------------------------------------------------------
+sub seq-error( Str:D $message )
+#-------------------------------------------------------------------------------
+{
+ "Error: $message".note if $VERBOSE;
+}
+
+#-------------------------------------------------------------------------------
+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,2,4|2,3
+ Example 2|1,2,3,4|-1
+ Example 3|1,2,3,3|3,4
+ END
+}
+
+################################################################################