aboutsummaryrefslogtreecommitdiff
path: root/challenge-077/athanasius
diff options
context:
space:
mode:
authorPerlMonk Athanasius <PerlMonk.Athanasius@gmail.com>2020-09-13 02:33:07 -0700
committerPerlMonk Athanasius <PerlMonk.Athanasius@gmail.com>2020-09-13 02:33:07 -0700
commitb5749d01705c4c3e99ddaa1a0e87d07da1d4b4e1 (patch)
tree602ec8c87b0d9b0ffd14c281bf78345ada5f4a8f /challenge-077/athanasius
parent94243bd5e0988d280b2ebd4afc0dbc3ad125c956 (diff)
downloadperlweeklychallenge-club-b5749d01705c4c3e99ddaa1a0e87d07da1d4b4e1.tar.gz
perlweeklychallenge-club-b5749d01705c4c3e99ddaa1a0e87d07da1d4b4e1.tar.bz2
perlweeklychallenge-club-b5749d01705c4c3e99ddaa1a0e87d07da1d4b4e1.zip
Perl & Raku solutions to Tasks 1 & 2 of the Perl Weekly Challenge #077
On branch branch-for-challenge-077 Changes to be committed: new file: challenge-077/athanasius/perl/ch-1.pl new file: challenge-077/athanasius/perl/ch-2.pl new file: challenge-077/athanasius/raku/ch-1.raku new file: challenge-077/athanasius/raku/ch-2.raku
Diffstat (limited to 'challenge-077/athanasius')
-rw-r--r--challenge-077/athanasius/perl/ch-1.pl252
-rw-r--r--challenge-077/athanasius/perl/ch-2.pl167
-rw-r--r--challenge-077/athanasius/raku/ch-1.raku215
-rw-r--r--challenge-077/athanasius/raku/ch-2.raku174
4 files changed, 808 insertions, 0 deletions
diff --git a/challenge-077/athanasius/perl/ch-1.pl b/challenge-077/athanasius/perl/ch-1.pl
new file mode 100644
index 0000000000..a2d7ea0398
--- /dev/null
+++ b/challenge-077/athanasius/perl/ch-1.pl
@@ -0,0 +1,252 @@
+#!perl
+
+###############################################################################
+=comment
+
+Perl Weekly Challenge 077
+=========================
+
+Task #1
+-------
+*Fibonacci Sum*
+
+Submitted by: Mohammad S Anwar
+
+You are given a positive integer $N.
+
+UPDATE: 2020-09-07 09:00:00
+Write a script to find out all possible combination of Fibonacci Numbers
+required to get $N on addition.
+
+You are *NOT* allowed to repeat a number. Print 0 if none found.
+
+Example 1:
+
+ Input: $N = 6
+
+ Output:
+ 1 + 2 + 3 = 6
+ 1 + 5 = 6
+
+Example 2:
+
+ Input: $N = 9
+
+ Output:
+ 1 + 8 = 9
+ 1 + 3 + 5 = 9
+
+=cut
+###############################################################################
+
+#--------------------------------------#
+# Copyright © 2020 PerlMonk Athanasius #
+#--------------------------------------#
+
+#==============================================================================
+=begin comment
+
+Notes
+-----
+
+The Fibonacci numbers are: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...
+[1],[2], but for this Task they are taken to be: 1, 2, 3, 5, 8, 13, 21, ...
+--i.e., 0 is excluded, and 1 is included only once. So the Task may be restated
+as follows: find all distinct subsets of the set { 1, 2, 3, 4, 8, 13, 21, ... }
+such that the sum of their members equals $N.
+
+Note also that "positive integer" is taken to mean "Natural number", i.e., an
+integer > 0, so the case of $N = 0 is excluded.
+
+I have not found any value for $N which produces an empty solution set.
+
+Memoization: For small values of $N, the calculation is already fast and memoi-
+zation has little effect. But for larger values, the speedup is significant.
+For example, with $N = 98,765,432 (2,218 combinations):
+
+ ------------------------------------------------------------
+ Rec. calls Time (s) Cache (bytes)
+ ------------------------------------------------------------
+ Without memoization: 453,275 22.12 --
+ With memoization: 30 0.15 13,890,979
+ ------------------------------------------------------------
+
+or with $N = 987,654,321 (4,997 combinations):
+
+ ------------------------------------------------------------
+ Rec. calls Time (s) Cache (bytes)
+ ------------------------------------------------------------
+ Without memoization: 6,692,527 275.00 --
+ With memoization: 35 0.23 30,212,067
+ ------------------------------------------------------------
+
+[1] https://oeis.org/A000045
+[2] https://en.wikipedia.org/wiki/Fibonacci_number
+
+=cut
+#==============================================================================
+
+ # Exports:
+use strict;
+use warnings;
+use Const::Fast; # const()
+use Getopt::Long; # GetOptions()
+use List::MoreUtils qw( firstidx lastidx none );
+use Memoize; # memoize()
+use Regexp::Common qw( number ); # %RE{num}
+
+#------------------------------------------------------------------------------
+# Constant
+#------------------------------------------------------------------------------
+
+const my $USAGE =>
+"Usage:
+ perl $0 [--hide-sums] <N>
+
+ <N> The target sum (a positive integer)
+ --hide-sums Suppress display of all the distinct combinations?\n";
+
+#------------------------------------------------------------------------------
+# File-local variables
+#------------------------------------------------------------------------------
+
+my @f_Fibonacci; # Fibonacci numbers: 1, 2, 3, 5, 8, 13, ...
+my %f_Cum_sums; # Fibonacci numbers (keys) and their cumulative sums (vals)
+
+#------------------------------------------------------------------------------
+BEGIN
+#------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 077, Task #1: Fibonacci Sum (Perl)\n\n";
+}
+
+#==============================================================================
+MAIN:
+#==============================================================================
+{
+ my ($N, $hide_sums) = parse_command_line();
+
+ init_fib_nums($N);
+
+ memoize('find_fib_sums');
+
+ my @sums = find_fib_sums($N);
+
+ display_results($N, \@sums, $hide_sums);
+}
+
+#------------------------------------------------------------------------------
+sub find_fib_sums # Recursive subroutine
+#------------------------------------------------------------------------------
+{
+ my ($N) = @_;
+ my @terms;
+
+ if ($N == 0) # Base case (a): 0 --> empty sum
+ {
+ @terms = ( [] );
+ }
+ elsif ($N <= 2) # Base cases (b) & (c): 1 --> 1, 2 --> 2
+ {
+ @terms = ( [$N] );
+ }
+ else # Recursive cases
+ {
+ my $max = lastidx { $_ <= $N } @f_Fibonacci;
+ my $min = firstidx { $f_Cum_sums{$_} >= $N } @f_Fibonacci;
+
+ for my $f (reverse @f_Fibonacci[$min .. $max])
+ {
+ my @prev_terms = find_fib_sums($N - $f);
+ my @new_terms;
+
+ for my $t (@prev_terms)
+ {
+ if (none { $_ == $f } @$t)
+ {
+ # N.B. Can't push to @$t, because $t (an array reference)
+ # is already entered in the memoization cache; pushing to
+ # @$t corrupts the cache data
+
+ push @new_terms, [@$t, $f];
+ }
+ # else: $f is already present in @$t, so omit $t from @new_terms
+ }
+
+ push @terms, @new_terms;
+ }
+ }
+
+ return @terms;
+}
+
+#------------------------------------------------------------------------------
+sub parse_command_line
+#------------------------------------------------------------------------------
+{
+ my $hide_sums = 0;
+
+ GetOptions
+ (
+ 'hide-sums' => \$hide_sums,
+
+ ) or die "ERROR in command line arguments\n$USAGE";
+
+ my $args = scalar @ARGV;
+ $args == 1 or die "ERROR: Found $args command-line arguments, " .
+ "expected 1\n$USAGE";
+
+ my $N = $ARGV[0];
+ $N =~ /\A$RE{num}{int}\z/
+ or die "ERROR: \$N ($N) must be an integer\n$USAGE";
+ $N > 0 or die "ERROR: \$N ($N) must be > 0\n$USAGE";
+
+ return ($N, $hide_sums);
+}
+
+#------------------------------------------------------------------------------
+sub init_fib_nums
+#------------------------------------------------------------------------------
+{
+ @f_Fibonacci = (1, 2);
+ %f_Cum_sums = (1 => 1, 2 => 3);
+
+ my ($N) = @_;
+ my $fib = 2;
+ my $sum = 3;
+
+ until ($fib >= $N)
+ {
+ $fib = $f_Fibonacci[-2] + $f_Fibonacci[-1];
+
+ push @f_Fibonacci, $fib;
+
+ $sum += $fib;
+
+ $f_Cum_sums{ $fib } = $sum;
+ }
+}
+
+#------------------------------------------------------------------------------
+sub display_results
+#------------------------------------------------------------------------------
+{
+ my ($N, $sums, $hide_sums) = @_;
+ my $count = scalar @$sums;
+
+ printf "Input: \$N = %d\n\n" .
+ "Output: %d %scombination%s of Fibonacci numbers sum%s to %d%s\n",
+ $N, $count, $count == 1 ? '' : 'different ',
+ $count == 1 ? '' : 's',
+ $count == 1 ? 's' : '',
+ $N, $count == 0 || $hide_sums ? '' : ':';
+
+ unless ($hide_sums)
+ {
+ printf " %s = %d\n", join(' + ', sort { $a <=> $b } @$_), $N
+ for @$sums;
+ }
+}
+
+###############################################################################
diff --git a/challenge-077/athanasius/perl/ch-2.pl b/challenge-077/athanasius/perl/ch-2.pl
new file mode 100644
index 0000000000..05b00b1302
--- /dev/null
+++ b/challenge-077/athanasius/perl/ch-2.pl
@@ -0,0 +1,167 @@
+#!perl
+
+###############################################################################
+=comment
+
+Perl Weekly Challenge 077
+=========================
+
+Task #2
+-------
+*Lonely X*
+
+Submitted by: Mohammad S Anwar
+
+You are given m x n character matrix consists of O and X only.
+
+Write a script to count the total number of X surrounded by O only. Print 0 if
+none found.
+
+Example 1:
+
+ Input: [ O O X ]
+ [ X O O ]
+ [ X O O ]
+
+ Output: 1 as there is only one X at the first row last column surrounded by
+ only O.
+
+Example 2:
+
+ Input: [ O O X O ]
+ [ X O O O ]
+ [ X O O X ]
+ [ O X O O ]
+
+ Output: 2
+
+ a) First X found at Row 1 Col 3.
+
+ b) Second X found at Row 3 Col 4.
+
+=cut
+###############################################################################
+
+#--------------------------------------#
+# Copyright © 2020 PerlMonk Athanasius #
+#--------------------------------------#
+
+use strict;
+use warnings;
+use Const::Fast;
+
+const my $USAGE =>
+"Usage:
+ perl $0 [<rows> ...]
+
+ [<rows> ...] 1+ same-width rows, each a string of 'O' and 'X' chars\n";
+
+#------------------------------------------------------------------------------
+BEGIN
+#------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 077, Task #2: Lonely X (Perl)\n\n";
+}
+
+#==============================================================================
+MAIN:
+#==============================================================================
+{
+ my $matrix = get_matrix(@ARGV);
+
+ print_matrix($matrix);
+
+ my $lonelyX = find_lonely_X($matrix);
+ my $count = scalar @$lonelyX;
+
+ print " Output: $count\n", $count ? "\n" : '';
+
+ my $i = 0;
+ printf " %d. Lonely X found at Row %d Col %d\n", ++$i, @$_ for @$lonelyX;
+}
+
+#------------------------------------------------------------------------------
+sub find_lonely_X
+#------------------------------------------------------------------------------
+{
+ my ($matrix) = @_;
+
+ my @lonely_X;
+ my $max_row = $#$matrix;
+ my $max_col = $#{ $matrix->[0] };
+
+ for my $row (0 .. $max_row)
+ {
+ COLUMN: for my $col (0 .. $max_col)
+ {
+ if ($matrix->[$row][$col] eq 'X')
+ {
+ for my $row_delta (-1, 0, 1)
+ {
+ my $neighbr_row = $row + $row_delta;
+ next if $neighbr_row < 0 ||
+ $neighbr_row > $max_row;
+
+ for my $col_delta (-1, 0, 1)
+ {
+ next if $row_delta == 0 &&
+ $col_delta == 0; # Self, not neighbour!
+
+ my $neighbr_col = $col + $col_delta;
+ next if $neighbr_col < 0 ||
+ $neighbr_col > $max_col;
+
+ next COLUMN # This X is not lonely
+ if $matrix->[$neighbr_row][$neighbr_col] eq 'X';
+ }
+ }
+
+ push @lonely_X, [$row + 1, $col + 1]; # A lonely X
+ }
+ }
+ }
+
+ return \@lonely_X;
+}
+
+#------------------------------------------------------------------------------
+sub get_matrix
+#------------------------------------------------------------------------------
+{
+ my @rows = @_;
+
+ scalar @rows > 0 or die $USAGE;
+
+ my $width = length $rows[0];
+ my @matrix;
+
+ for my $i (0 .. $#rows)
+ {
+ my $row = $rows[$i];
+
+ $row =~ / ( [^OX] ) /x
+ and die "Invalid character '$1' in the input matrix\n$USAGE";
+
+ length $row == $width
+ or die 'Inconsistent number of columns in row ' . ($i + 1) .
+ "\n$USAGE";
+
+ $matrix[$i] = [ split '', $row ];
+ }
+
+ return \@matrix;
+}
+
+#------------------------------------------------------------------------------
+sub print_matrix
+#------------------------------------------------------------------------------
+{
+ my ($matrix) = @_;
+
+ printf " Input: [ %s ]\n", join ' ', @{ $matrix->[0 ] };
+ printf " [ %s ]\n", join ' ', @{ $matrix->[$_] } for 1 .. $#$matrix;
+ print "\n";
+}
+
+###############################################################################
diff --git a/challenge-077/athanasius/raku/ch-1.raku b/challenge-077/athanasius/raku/ch-1.raku
new file mode 100644
index 0000000000..9cbb281b3d
--- /dev/null
+++ b/challenge-077/athanasius/raku/ch-1.raku
@@ -0,0 +1,215 @@
+use v6d;
+
+###############################################################################
+=begin comment
+
+Perl Weekly Challenge 077
+=========================
+
+Task #1
+-------
+*Fibonacci Sum*
+
+Submitted by: Mohammad S Anwar
+
+You are given a positive integer $N.
+
+UPDATE: 2020-09-07 09:00:00
+Write a script to find out all possible combination of Fibonacci Numbers
+required to get $N on addition.
+
+You are *NOT* allowed to repeat a number. Print 0 if none found.
+
+Example 1:
+
+ Input: $N = 6
+
+ Output:
+ 1 + 2 + 3 = 6
+ 1 + 5 = 6
+
+Example 2:
+
+ Input: $N = 9
+
+ Output:
+ 1 + 8 = 9
+ 1 + 3 + 5 = 9
+
+=end comment
+###############################################################################
+
+#--------------------------------------#
+# Copyright © 2020 PerlMonk Athanasius #
+#--------------------------------------#
+
+#==============================================================================
+=begin comment
+
+Notes
+-----
+
+The Fibonacci numbers are: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...
+[1],[2], but for this Task they are taken to be: 1, 2, 3, 5, 8, 13, 21, ...
+--i.e., 0 is excluded, and 1 is included only once. So the Task may be restated
+as follows: find all distinct subsets of the set { 1, 2, 3, 4, 8, 13, 21, ... }
+such that the sum of their members equals $N.
+
+Note also that "positive integer" is taken to mean "Natural number", i.e., an
+integer > 0, so the case of $N = 0 is excluded.
+
+I have not found any value for $N which produces an empty solution set.
+
+Memoization: For small values of $N, the calculation is already fast and memo-
+ization has little effect. But for larger values, the speedup is significant.
+For example, with $N = 9,876,543:
+
+ --------------------------------------------
+ Rec. calls Time (s)
+ --------------------------------------------
+ Without memoization: 24,451 19.61
+ With memoization: 23 1.73
+ --------------------------------------------
+
+or with $N = 98,765,432:
+
+ --------------------------------------------
+ Rec. calls Time (s)
+ --------------------------------------------
+ Without memoization: 453,275 545.24
+ With memoization: 30 8.60
+ --------------------------------------------
+
+[1] https://oeis.org/A000045
+[2] https://en.wikipedia.org/wiki/Fibonacci_number
+
+=end comment
+#==============================================================================
+
+use List::MoreUtils < firstidx lastidx >;
+use Memoize;
+
+#------------------------------------------------------------------------------
+# File-local variables
+#------------------------------------------------------------------------------
+
+my UInt @f_Fibonacci; # Fibonacci nums: 1, 2, 3, 5, 8, 13, ...
+my UInt %f_Cum-sums; # Fibonacci nums (keys) & their cumulative sums (vals)
+
+#------------------------------------------------------------------------------
+BEGIN
+#------------------------------------------------------------------------------
+{
+ "\nChallenge 077, Task #1: Fibonacci Sum (Raku)\n".put;
+}
+
+##=============================================================================
+sub MAIN
+(
+ UInt:D $N where { $N > 0 }, #= The target sum (a positive integer)
+ Bool:D :$hide-sums = False, #= Suppress display of all the distinct
+ #= combinations?
+)
+##=============================================================================
+{
+ init-fib-nums($N);
+
+ memoize(&find-fib-sums);
+
+ my Array[UInt] @sums = find-fib-sums($N);
+
+ display-results($N, @sums, $hide-sums);
+}
+
+#------------------------------------------------------------------------------
+sub find-fib-sums # Recursive subroutine
+(
+ UInt:D $N # Note: 0 must be allowed here!
+--> Array:D[Array:D[UInt:D]]
+)
+#------------------------------------------------------------------------------
+{
+ my Array[UInt] @sums;
+
+ if $N == 0 # Base case (a): 0 --> empty sum
+ {
+ @sums.push: Array[UInt].new();
+ }
+ elsif $N <= 2 # Base cases (b) & (c): 1 --> 1, 2 --> 2
+ {
+ @sums.push: Array[UInt].new($N);
+ }
+ else # Recursive cases
+ {
+ my UInt $max = lastidx { $_ <= $N }, @f_Fibonacci;
+ my UInt $min = firstidx { %f_Cum-sums{$_} >= $N }, @f_Fibonacci;
+
+ for @f_Fibonacci[$min .. $max].reverse -> UInt $f
+ {
+ my Array[UInt] @prev-terms = find-fib-sums($N - $f);
+ my Array[UInt] @new-terms;
+
+ for @prev-terms -> Array[UInt] $term
+ {
+ @new-terms.push: Array[UInt].new(|$term, $f) if $f ∉ $term;
+ }
+
+ @sums.append: @new-terms;
+ }
+ }
+
+ return @sums;
+}
+
+#------------------------------------------------------------------------------
+sub init-fib-nums( UInt:D $N )
+#------------------------------------------------------------------------------
+{
+ @f_Fibonacci = 1, 2;
+ %f_Cum-sums = 1 => 1, 2 => 3;
+
+ my UInt $fib = 2;
+ my UInt $sum = 3;
+
+ until $fib >= $N
+ {
+ $fib = @f_Fibonacci[*-2] + @f_Fibonacci[*-1];
+
+ @f_Fibonacci.push: $fib;
+
+ $sum += $fib;
+
+ %f_Cum-sums{ $fib } = $sum;
+ }
+}
+
+#------------------------------------------------------------------------------
+sub display-results( UInt:D $N, Array:D[UInt:D] @sums, Bool:D $hide-sums )
+#------------------------------------------------------------------------------
+{
+ my UInt $count = @sums.elems;
+
+ ("Input: \$N = %d\n\n" ~
+ "Output: %d %scombination%s of Fibonacci numbers sum%s to %d%s\n").printf:
+ $N, $count, $count == 1 ?? '' !! 'different ',
+ $count == 1 ?? '' !! 's',
+ $count == 1 ?? 's' !! '',
+ $N, $count == 0 || $hide-sums ?? '' !! ':';
+
+ unless $hide-sums
+ {
+ " %s = %d\n".printf: .sort.join(' + '), $N for @sums;
+ }
+}
+
+#------------------------------------------------------------------------------
+sub USAGE()
+#------------------------------------------------------------------------------
+{
+ my Str $usage = $*USAGE;
+
+ $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/;
+ $usage.put;
+}
+
+###############################################################################
diff --git a/challenge-077/athanasius/raku/ch-2.raku b/challenge-077/athanasius/raku/ch-2.raku
new file mode 100644
index 0000000000..ddfd0ab646
--- /dev/null
+++ b/challenge-077/athanasius/raku/ch-2.raku
@@ -0,0 +1,174 @@
+use v6d;
+
+###############################################################################
+=begin comment
+
+Perl Weekly Challenge 077
+=========================
+
+Task #2
+-------
+*Lonely X*
+
+Submitted by: Mohammad S Anwar
+
+You are given m x n character matrix consists of O and X only.
+
+Write a script to count the total number of X surrounded by O only. Print 0 if
+none found.
+
+Example 1:
+
+ Input: [ O O X ]
+ [ X O O ]
+ [ X O O ]
+
+ Output: 1 as there is only one X at the first row last column surrounded by
+ only O.
+
+Example 2:
+
+ Input: [ O O X O ]
+ [ X O O O ]
+ [ X O O X ]
+ [ O X O O ]
+
+ Output: 2
+
+ a) First X found at Row 1 Col 3.
+
+ b) Second X found at Row 3 Col 4.
+
+=end comment
+###############################################################################
+
+#--------------------------------------#
+# Copyright © 2020 PerlMonk Athanasius #
+#--------------------------------------#
+
+#------------------------------------------------------------------------------
+BEGIN
+#------------------------------------------------------------------------------
+{
+ "\nChallenge 077, Task #2: Lonely X (Raku)\n".put;
+}
+
+##=============================================================================
+sub MAIN
+(
+ *@rows where { @rows .elems > 0 && #= 1+ same-width rows, each a
+ @rows[0].chars > 0 } #= string of 'O' and 'X' chars
+)
+##=============================================================================
+{
+ my Str @str-rows = @rows;
+ my Array[Str] @matrix = get-matrix(@str-rows);
+ print-matrix( @matrix );
+
+ my Pair @lonely-X = find-lonely-X(@matrix);
+ my UInt $count = @lonely-X.elems;
+
+ " Output: %d\n%s".printf: $count, $count ?? "\n" !! '';
+
+ my UInt $i = 0;
+ " %d. Lonely X found at Row %d Col %d\n".printf: ++$i, .kv for @lonely-X;
+}
+
+#------------------------------------------------------------------------------
+sub find-lonely-X( Array:D[Str:D] @matrix --> Array:D[Pair:D] )
+#------------------------------------------------------------------------------
+{
+ my Pair @lonely-X;
+ my UInt $max-row = @matrix.end;
+ my UInt $max-col = @matrix[0].elems - 1;
+
+ for 0 .. $max-row -> UInt $row
+ {
+ COLUMN: for 0 .. $max-col -> UInt $col
+ {
+ if @matrix[$row; $col] eq 'X'
+ {
+ for -1, 0, 1 -> Int $row-delta
+ {
+ my Int $neighbour-row = $row + $row-delta;
+ next if $neighbour-row < 0 ||
+ $neighbour-row > $max-row;
+
+ for -1, 0, 1 -> Int $col-delta
+ {
+ next if $row-delta == 0 &&
+ $col-delta == 0; # Self, not neighbour!
+
+ my Int $neighbour-col = $col + $col-delta;
+ next if $neighbour-col < 0 ||
+ $neighbour-col > $max-col;
+
+ next COLUMN # This X is not lonely
+ if @matrix[$neighbour-row; $neighbour-col] eq 'X';
+ }
+ }
+
+ push @lonely-X, Pair.new($row + 1, $col + 1); # A lonely X
+ }
+ }
+ }
+
+ return @lonely-X;
+}
+
+#------------------------------------------------------------------------------
+sub get-matrix( Str:D @rows --> Array:D[Str:D] )
+#------------------------------------------------------------------------------
+{
+ my UInt $width = @rows[0].chars;
+ my Array[Str] @matrix[ @rows.elems ];
+
+ for 0 .. @rows.end -> UInt $i
+ {
+ my Str $row = @rows[$i];
+
+ $row ~~ / ( <-[ O X ]> ) /
+ and error("Invalid character '$0' in the input matrix");
+
+ $row.chars == $width
+ or error("Inconsistent number of columns in row { $i + 1 }");
+
+ my Str @chars = $row.split: '', :skip-empty;
+ @matrix[$i] = @chars;
+ }
+
+ return @matrix;
+}
+
+#------------------------------------------------------------------------------
+sub print-matrix( Array:D[Str:D] @matrix )
+#------------------------------------------------------------------------------
+{
+ " Input: [ %s ]\n".printf: @matrix[0 ].join: ' ';
+ " [ %s ]\n".printf: @matrix[$_].join: ' ' for 1 .. @matrix.end;
+
+ ''.put;
+}
+
+#------------------------------------------------------------------------------
+sub error( Str:D $message )
+#------------------------------------------------------------------------------
+{
+ "ERROR: $message".put;
+
+ USAGE();
+
+ exit;
+}
+
+#------------------------------------------------------------------------------
+sub USAGE()
+#------------------------------------------------------------------------------
+{
+ my Str $usage = $*USAGE;
+
+ $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/;
+ $usage.put;
+}
+
+###############################################################################