aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-347/athanasius/perl/ch-1.pl249
-rw-r--r--challenge-347/athanasius/perl/ch-2.pl192
-rw-r--r--challenge-347/athanasius/raku/ch-1.raku257
-rw-r--r--challenge-347/athanasius/raku/ch-2.raku185
4 files changed, 883 insertions, 0 deletions
diff --git a/challenge-347/athanasius/perl/ch-1.pl b/challenge-347/athanasius/perl/ch-1.pl
new file mode 100644
index 0000000000..9f4c04a94c
--- /dev/null
+++ b/challenge-347/athanasius/perl/ch-1.pl
@@ -0,0 +1,249 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 347
+=========================
+
+TASK #1
+-------
+*Format Date*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given a date in the form: 10th Nov 2025.
+
+Write a script to format the given date in the form: 2025-11-10 using the set
+below.
+
+ @DAYS = ("1st", "2nd", "3rd", ....., "30th", "31st")
+ @MONTHS = ("Jan", "Feb", "Mar", ....., "Nov", "Dec")
+ @YEARS = (1900..2100)
+
+Example 1
+
+ Input: $str = "1st Jan 2025"
+ Output: "2025-01-01"
+
+Example 2
+
+ Input: $str = "22nd Feb 2025"
+ Output: "2025-02-22"
+
+Example 3
+
+ Input: $str = "15th Apr 2025"
+ Output: "2025-04-15"
+
+Example 4
+
+ Input: $str = "23rd Oct 2025"
+ Output: "2025-10-23"
+
+Example 5
+
+ Input: $str = "31st Dec 2025"
+ Output: "2025-12-31"
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2025 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=comment
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. A date in the form "10th Nov 2025" is entered on the command-line, either:
+ i. as a single string; or
+ ii. as three separate strings.
+
+Date Validity
+-------------
+Valid dates are defined by the set (@DAYS, @MONTHS, @YEARS). Dates falling out-
+side this set (e.g., "21th Jan 2025", "1st XYZ 2025", "1st Jan 1899") are
+rejected. Dates falling within the set are accepted and formatted; but, if they
+are in fact invalid (e.g., "31st Apr 2025", "29th Feb 2025"), they are flagged
+as such in an appended message.
+
+Leap Years
+----------
+From https://en.wikipedia.org/wiki/Leap_year#Gregorian_calendar
+"Every year that is exactly divisible by four is a leap year, except for years
+ that are exactly divisible by 100, but these centurial years are leap years if
+ they are exactly divisible by 400. For example, the years 1700, 1800, and 1900
+ are not leap years, but the years 1600 and 2000 are."
+
+=cut
+#===============================================================================
+
+use v5.38.2; # Enables strictures
+use warnings;
+use Const::Fast;
+use List::MoreUtils qw( any firstidx firstval );
+use Test::More;
+use enum qw( VALID OUT_OF_RANGE NOT_A_LEAP_YEAR );
+
+const my @DAYS => qw( 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
+ 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th
+ 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st );
+const my @MONTHS => qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
+const my @YEARS => (1900 .. 2100);
+
+const my $USAGE => <<END;
+Usage:
+ perl $0 <str>
+ perl $0 <date> <month> <year>
+ perl $0
+
+ <str> A date with the format "10th Nov 2025"
+ <date> A date such as "1st", "22nd", or "30th"
+ <month> A month such as "Jan" or "Feb"
+ <year> A year in the range 1900 to 2100 inclusive
+END
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 347, Task #1: Format Date (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ my $argc = scalar @ARGV;
+
+ if ($argc == 0)
+ {
+ run_tests();
+ }
+ elsif ($argc == 1)
+ {
+ main( $ARGV[0] );
+ }
+ elsif ($argc == 3)
+ {
+ main( join ' ', @ARGV );
+ }
+ else
+ {
+ error( "Expected 0, 1, or 3 command-line arguments, found $argc" );
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub main
+#-------------------------------------------------------------------------------
+{
+ my ($str) = @_;
+
+ print qq[Input: \$str = "$str"\n];
+
+ my ($status, $date) = format_date( $str );
+
+ print qq[Output: "$date"\n];
+
+ if ($status == OUT_OF_RANGE)
+ {
+ print "\nNote: The date is invalid: out of range\n";
+ }
+ elsif ($status == NOT_A_LEAP_YEAR)
+ {
+ print "\nNote: The date is invalid: not a leap year\n";
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub format_date
+#-------------------------------------------------------------------------------
+{
+ my ($str) = @_;
+ my $status = VALID;
+
+ my ($day, $month, $year) = $str =~ / ^ (\w{3,4}) \s (\w{3}) \s (\d{4}) $ /x
+ or error( 'The input date is incorrectly formatted' );
+
+ firstval { $_ eq $day } @DAYS
+ or error( 'The day "' . $day . '" is invalid' );
+ firstval { $_ eq $month } @MONTHS
+ or error( 'The month "' . $month . '" is invalid' );
+ firstval { $_ eq $year } @YEARS
+ or error( 'The year "' . $year . '" is invalid' );
+
+ my ($date) = $day =~ / ^ (\d{1,2}) /x;
+
+ if ($month eq 'Feb')
+ {
+ if ($date == 29)
+ {
+ $status = NOT_A_LEAP_YEAR if ($year % 4) ||
+ (!($year % 100) && ($year % 400));
+ }
+ elsif ($date >= 30)
+ {
+ $status = OUT_OF_RANGE;
+ }
+ }
+ elsif (any { $_ eq $month } qw( Apr Jun Sep Nov ))
+ {
+ $status = OUT_OF_RANGE if $date == 31;
+ }
+
+ my $formatted_date = sprintf '%4d-%02d-%02d',
+ $year, (firstidx { $_ eq $month } @MONTHS) + 1, $date;
+
+ return ($status, $formatted_date);
+}
+
+#-------------------------------------------------------------------------------
+sub run_tests
+#-------------------------------------------------------------------------------
+{
+ print "Running the test suite\n";
+
+ while (my $line = <DATA>)
+ {
+ chomp $line;
+
+ my ($test_name, $str, $expected) = split / \| /x, $line;
+
+ for ($test_name, $str, $expected)
+ {
+ s/ ^ \s+ //x;
+ s/ \s+ $ //x;
+ }
+
+ my ($status, $date) = format_date( $str );
+
+ $status == VALID or die "Invalid date: $str";
+
+ is $date, $expected, $test_name;
+ }
+
+ done_testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "\nERROR: $message\n$USAGE";
+}
+
+################################################################################
+
+__DATA__
+Example 1| 1st Jan 2025|2025-01-01
+Example 2|22nd Feb 2025|2025-02-22
+Example 3|15th Apr 2025|2025-04-15
+Example 4|23rd Oct 2025|2025-10-23
+Example 5|31st Dec 2025|2025-12-31
diff --git a/challenge-347/athanasius/perl/ch-2.pl b/challenge-347/athanasius/perl/ch-2.pl
new file mode 100644
index 0000000000..0106732f6f
--- /dev/null
+++ b/challenge-347/athanasius/perl/ch-2.pl
@@ -0,0 +1,192 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 347
+=========================
+
+TASK #2
+-------
+*Format Phone Number*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given a phone number as a string containing digits, space and dash only.
+
+Write a script to format the given phone number using the below rules:
+
+ 1. Removing all spaces and dashes
+ 2. Grouping digits into blocks of length 3 from left to right
+ 3. Handling the final digits (4 or fewer) specially:
+ - 2 digits: one block of length 2
+ - 3 digits: one block of length 3
+ - 4 digits: two blocks of length 2
+ 4. Joining all blocks with dashes
+
+Example 1
+
+ Input: $phone = "1-23-45-6"
+ Output: "123-456"
+
+Example 2
+
+ Input: $phone = "1234"
+ Output: "12-34"
+
+Example 3
+
+ Input: $phone = "12 345-6789"
+ Output: "123-456-789"
+
+Example 4
+
+ Input: $phone = "123 4567"
+ Output: "123-45-67"
+
+Example 5
+
+ Input: $phone = "123 456-78"
+ Output: "123-456-78"
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2025 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=comment
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. A phone number is entered on the command-line as a single string containing
+ digits, spaces, and dashes (hyphens) only.
+
+Assumptions
+-----------
+1. A phone number contains at least 2 digits.
+2. Spaces and dashes in a phone number are separators, and so do not occur in
+ either initial or final position.
+
+=cut
+#===============================================================================
+
+use v5.38.2; # Enables strictures
+use warnings;
+use Const::Fast;
+use Test::More;
+
+const my $USAGE => <<END;
+Usage:
+ perl $0 <phone>
+ perl $0
+
+ <phone> A string containing digits, spaces, and dashes only
+END
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 347, Task #2: Format Phone Number (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ my $argc = scalar @ARGV;
+
+ if ($argc == 0)
+ {
+ run_tests();
+ }
+ elsif ($argc == 1)
+ {
+ my ($phone) = @ARGV;
+ $phone =~ / ^ \d [\d\s-]* \d $ /x
+ or error( 'Invalid phone number' );
+
+ print qq[Input: \$phone = "$phone"\n];
+
+ my $formatted_num = format_phone_number( $phone );
+
+ print qq[Output: "$formatted_num"\n];
+ }
+ else
+ {
+ error( "Expected 1 or 0 command-line arguments, found $argc" );
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub format_phone_number
+#-------------------------------------------------------------------------------
+{
+ my ($phone) = @_;
+ $phone =~ / ^ \d [\d\s-]* \d $ /x
+ or die 'Invalid phone number';
+
+ $phone =~ s/ \s //gx;
+ $phone =~ s/ \- //gx;
+
+ my @blocks = $phone =~ / (.{1,3}) /gx;
+
+ if (length $blocks[-1] == 1)
+ {
+ my $ult = \$blocks[-1];
+ my $pen = \$blocks[-2];
+ my $c = substr $$pen, -1, 1, '';
+ $$ult = $c . $$ult;
+ }
+
+ return join '-', @blocks;
+}
+
+#-------------------------------------------------------------------------------
+sub run_tests
+#-------------------------------------------------------------------------------
+{
+ print "Running the test suite\n";
+
+ while (my $line = <DATA>)
+ {
+ chomp $line;
+
+ my ($test_name, $phone, $expected) = split / \| /x, $line;
+
+ for ($test_name, $phone, $expected)
+ {
+ s/ ^ \s+ //x;
+ s/ \s+ $ //x;
+ }
+
+ my $formatted_num = format_phone_number( $phone );
+
+ is $formatted_num, $expected, $test_name;
+ }
+
+ done_testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+################################################################################
+
+__DATA__
+Example 1|1-23-45-6 |123-456
+Example 2|1234 |12-34
+Example 3|12 345-6789|123-456-789
+Example 4|123 4567 |123-45-67
+Example 5|123 456-78 |123-456-78
diff --git a/challenge-347/athanasius/raku/ch-1.raku b/challenge-347/athanasius/raku/ch-1.raku
new file mode 100644
index 0000000000..fb07fecc7c
--- /dev/null
+++ b/challenge-347/athanasius/raku/ch-1.raku
@@ -0,0 +1,257 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 347
+=========================
+
+TASK #1
+-------
+*Format Date*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given a date in the form: 10th Nov 2025.
+
+Write a script to format the given date in the form: 2025-11-10 using the set
+below.
+
+ @DAYS = ("1st", "2nd", "3rd", ....., "30th", "31st")
+ @MONTHS = ("Jan", "Feb", "Mar", ....., "Nov", "Dec")
+ @YEARS = (1900..2100)
+
+Example 1
+
+ Input: $str = "1st Jan 2025"
+ Output: "2025-01-01"
+
+Example 2
+
+ Input: $str = "22nd Feb 2025"
+ Output: "2025-02-22"
+
+Example 3
+
+ Input: $str = "15th Apr 2025"
+ Output: "2025-04-15"
+
+Example 4
+
+ Input: $str = "23rd Oct 2025"
+ Output: "2025-10-23"
+
+Example 5
+
+ Input: $str = "31st Dec 2025"
+ Output: "2025-12-31"
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2025 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=begin comment
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. A date in the form "10th Nov 2025" is entered on the command-line, either:
+ i. as a single string; or
+ ii. as three separate strings.
+
+Date Validity
+-------------
+Valid dates are defined by the set (@DAYS, @MONTHS, @YEARS). Dates falling out-
+side this set (e.g., "21th Jan 2025", "1st XYZ 2025", "1st Jan 1899") are
+rejected. Dates falling within the set are accepted and formatted; but, if they
+are in fact invalid (e.g., "31st Apr 2025", "29th Feb 2025"), they are flagged
+as such in an appended message.
+
+Leap Years
+----------
+From https://en.wikipedia.org/wiki/Leap_year#Gregorian_calendar
+"Every year that is exactly divisible by four is a leap year, except for years
+ that are exactly divisible by 100, but these centurial years are leap years if
+ they are exactly divisible by 400. For example, the years 1700, 1800, and 1900
+ are not leap years, but the years 1600 and 2000 are."
+
+=end comment
+#===============================================================================
+
+use Test;
+
+enum Status < Valid Out-of-range Not-a-leap-year >;
+subset Result of List where (Status, Str);
+
+my constant @DAYS = Array[Str].new:
+ < 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th
+ 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th
+ 21st 22nd 23rd 24th 25th 26th 27th 28th 29th 30th 31st >;
+my constant @MONTHS = Array[Str].new:
+ < Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec >;
+my constant @YEARS = Array[UInt].new: 1900 .. 2100;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 347, Task #1: Format Date (Raku)\n".put;
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ Str:D $str #= A date with the format "10th Nov 2025"
+)
+#===============================================================================
+{
+ main( $str );
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ Str:D $date, #= A date such as "1st", "22nd", or "30th"
+ Str:D $month, #= A month such as "Jan" or "Feb"
+ UInt:D $year #= A year in the range 1900 to 2100 inclusive
+)
+#===============================================================================
+{
+ main( "$date $month $year" );
+}
+
+#===============================================================================
+multi sub MAIN() # No input: run the test suite
+#===============================================================================
+{
+ run-tests();
+}
+
+#-------------------------------------------------------------------------------
+sub main( Str:D $str )
+#-------------------------------------------------------------------------------
+{
+ qq[Input: \$str = "$str"].put;
+
+ my (Status $status, Str $date) = format-date( $str );
+
+ qq[Output: "$date"].put;
+
+ if $status == Out-of-range
+ {
+ "\nNote: The date is invalid: out of range".put;
+ }
+ elsif $status == Not-a-leap-year
+ {
+ "\nNote: The date is invalid: not a leap year".put;
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub format-date( Str:D $str --> Result:D )
+#-------------------------------------------------------------------------------
+{
+ my Status $status = Valid;
+
+ $str ~~ / ^ (\w ** 3..4) \s (\w ** 3) \s (\d ** 4) $ /
+ or error( 'The input date is incorrectly formatted' );
+
+ my Str $day = ~$0;
+ my Str $month = ~$1;
+ my UInt $year = +$2;
+
+ @DAYS\ .first: $day or error( 'The day "' ~ $day ~ '" is invalid' );
+ @MONTHS.first: $month or error( 'The month "' ~ $month ~ '" is invalid' );
+ @YEARS\.first: $year or error( 'The year "' ~ $year ~ '" is invalid' );
+
+ my UInt $date = (S/ \D ** 2 $ // with $day).Int;
+
+ if $month eq 'Feb'
+ {
+ if $date == 29
+ {
+ $status = Not-a-leap-year if !($year %% 4) ||
+ (($year %% 100) && !($year %% 400));
+ }
+ elsif $date >= 30
+ {
+ $status = Out-of-range;
+ }
+ }
+ elsif $month eq < Apr Jun Sep Nov >.any
+ {
+ $status = Out-of-range if $date == 31;
+ }
+
+ my Str $formatted-date = '%4d-%02d-%02d'.sprintf:
+ $year, (@MONTHS.first: $month, :k) + 1, $date;
+
+ return ($status, $formatted-date);
+}
+
+#-------------------------------------------------------------------------------
+sub run-tests()
+#-------------------------------------------------------------------------------
+{
+ 'Running the test suite'.put;
+
+ for test-data.lines -> Str $line
+ {
+ my Str ($test-name, $str, $expected) = $line.split: / \| /;
+
+ for $test-name, $str, $expected
+ {
+ s/ ^ \s+ //;
+ s/ \s+ $ //;
+ }
+
+ my (Status $status, Str $date) = format-date( $str );
+
+ $status == Valid or die "Invalid date: $str";
+
+ is $date, $expected, $test-name;
+ }
+
+ done-testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error( Str:D $message )
+#-------------------------------------------------------------------------------
+{
+ "\nERROR: $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| 1st Jan 2025|2025-01-01
+ Example 2|22nd Feb 2025|2025-02-22
+ Example 3|15th Apr 2025|2025-04-15
+ Example 4|23rd Oct 2025|2025-10-23
+ Example 5|31st Dec 2025|2025-12-31
+ END
+}
+
+################################################################################
diff --git a/challenge-347/athanasius/raku/ch-2.raku b/challenge-347/athanasius/raku/ch-2.raku
new file mode 100644
index 0000000000..b9cf150b9f
--- /dev/null
+++ b/challenge-347/athanasius/raku/ch-2.raku
@@ -0,0 +1,185 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 347
+=========================
+
+TASK #2
+-------
+*Format Phone Number*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given a phone number as a string containing digits, space and dash only.
+
+Write a script to format the given phone number using the below rules:
+
+ 1. Removing all spaces and dashes
+ 2. Grouping digits into blocks of length 3 from left to right
+ 3. Handling the final digits (4 or fewer) specially:
+ - 2 digits: one block of length 2
+ - 3 digits: one block of length 3
+ - 4 digits: two blocks of length 2
+ 4. Joining all blocks with dashes
+
+Example 1
+
+ Input: $phone = "1-23-45-6"
+ Output: "123-456"
+
+Example 2
+
+ Input: $phone = "1234"
+ Output: "12-34"
+
+Example 3
+
+ Input: $phone = "12 345-6789"
+ Output: "123-456-789"
+
+Example 4
+
+ Input: $phone = "123 4567"
+ Output: "123-45-67"
+
+Example 5
+
+ Input: $phone = "123 456-78"
+ Output: "123-456-78"
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2025 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=begin comment
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. A phone number is entered on the command-line as a single string containing
+ digits, spaces, and dashes (hyphens) only.
+
+Assumptions
+-----------
+1. A phone number contains at least 2 digits.
+2. Spaces and dashes in a phone number are separators, and so do not occur in
+ either initial or final position.
+
+=end comment
+#===============================================================================
+
+use Test;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 347, Task #2: Format Phone Number (Raku)\n".put;
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ #| A string containing digits, spaces, and dashes only
+
+ Str:D $phone where { / ^ \d <[ \d \s - ]>* \d $ / }
+)
+#===============================================================================
+{
+ qq[Input: \$phone = "$phone"].put;
+
+ my Str $formatted-num = format-phone-number( $phone );
+
+ qq[Output: "$formatted-num"].put;
+}
+
+#===============================================================================
+multi sub MAIN() # No input: run the test suite
+#===============================================================================
+{
+ run-tests();
+}
+
+#-------------------------------------------------------------------------------
+sub format-phone-number
+(
+ Str:D $phone where { / ^ \d <[ \d \s - ]>* \d $ / }
+--> Str:D
+)
+#-------------------------------------------------------------------------------
+{
+ my $str = $phone;
+ $str ~~ s:g/ \s //;
+ $str ~~ s:g/ \- //;
+
+ my Match @matches = m:g/ (. ** 1..3) / given $str;
+ my Str @blocks = @matches.map: { ~$_ };
+
+ if @blocks[*-1].chars == 1
+ {
+ my $ult := @blocks[*-1];
+ my $pen := @blocks[*-2];
+
+ my Str $c = $pen.substr: *-1, 1;
+ $pen.substr-rw( *-1, 1 ) = '';
+ $ult = $c ~ $ult;
+ }
+
+ return @blocks.join: '-';
+}
+
+#-------------------------------------------------------------------------------
+sub run-tests()
+#-------------------------------------------------------------------------------
+{
+ 'Running the test suite'.put;
+
+ for test-data.lines -> Str $line
+ {
+ my Str ($test-name, $phone, $expected) = $line.split: / \| /;
+
+ for $test-name, $phone, $expected
+ {
+ s/ ^ \s+ //;
+ s/ \s+ $ //;
+ }
+
+ my Str $formatted-num = format-phone-number( $phone );
+
+ is $formatted-num, $expected, $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|1-23-45-6 |123-456
+ Example 2|1234 |12-34
+ Example 3|12 345-6789|123-456-789
+ Example 4|123 4567 |123-45-67
+ Example 5|123 456-78 |123-456-78
+ END
+}
+
+################################################################################