aboutsummaryrefslogtreecommitdiff
path: root/challenge-257
diff options
context:
space:
mode:
Diffstat (limited to 'challenge-257')
-rwxr-xr-xchallenge-257/archargelod/nim/ch_1.nim38
-rwxr-xr-xchallenge-257/archargelod/nim/ch_2.nim64
-rw-r--r--challenge-257/athanasius/perl/ch-1.pl177
-rw-r--r--challenge-257/athanasius/perl/ch-2.pl410
-rw-r--r--challenge-257/athanasius/raku/ch-1.raku178
-rw-r--r--challenge-257/athanasius/raku/ch-2.raku410
-rwxr-xr-xchallenge-257/e-choroba/perl/ch-1.pl27
-rwxr-xr-xchallenge-257/e-choroba/perl/ch-2.pl79
-rw-r--r--challenge-257/laurent-rosenfeld/blog.txt1
-rw-r--r--challenge-257/laurent-rosenfeld/julia/ch-1.jl22
-rw-r--r--challenge-257/laurent-rosenfeld/perl/ch-1.pl22
-rw-r--r--challenge-257/laurent-rosenfeld/raku/ch-1.raku17
-rw-r--r--challenge-257/mark-anderson/raku/ch-2.raku36
-rw-r--r--challenge-257/steven-wilson/python/ch-1.py29
-rw-r--r--challenge-257/wlmb/blog.txt1
-rwxr-xr-xchallenge-257/wlmb/perl/ch-1.pl15
-rwxr-xr-xchallenge-257/wlmb/perl/ch-2.pl28
17 files changed, 1541 insertions, 13 deletions
diff --git a/challenge-257/archargelod/nim/ch_1.nim b/challenge-257/archargelod/nim/ch_1.nim
new file mode 100755
index 0000000000..c1635ff5ec
--- /dev/null
+++ b/challenge-257/archargelod/nim/ch_1.nim
@@ -0,0 +1,38 @@
+#!/usr/bin/env -S nim r -d:release --verbosity:0 --hints:off
+import std/[sugar, algorithm]
+
+proc mapToSmallerValuesCount*(numbers: sink seq[int]): seq[int] =
+ ## ~10x faster than naive method
+ var indexed = collect(
+ for i, n in numbers:
+ (i, n)
+ )
+ indexed.sort((t1, t2) => cmp(t1[1], t2[1]))
+
+ result = numbers
+
+ var prev: tuple[val, index: int]
+ for curIndex, (origIndex, curVal) in indexed:
+ result[origIndex] =
+ if curVal == prev.val:
+ prev.index
+ else:
+ prev = (curVal, curIndex)
+ curIndex
+
+when isMainModule:
+ import std/unittest
+
+ const
+ Test = [@[5, 2, 1, 6], @[1, 2, 0, 3], @[0, 1], @[9, 4, 9, 2]]
+ Expected = [@[2, 1, 0, 3], @[1, 2, 0, 3], @[0, 1], @[2, 1, 2, 0]]
+
+ suite "Smaller than Current":
+ test "Example 1":
+ check mapToSmallerValuesCount(Test[0]) == Expected[0]
+ test "Example 2":
+ check mapToSmallerValuesCount(Test[1]) == Expected[1]
+ test "Example 3":
+ check mapToSmallerValuesCount(Test[2]) == Expected[2]
+ test "Example 4":
+ check mapToSmallerValuesCount(Test[3]) == Expected[3]
diff --git a/challenge-257/archargelod/nim/ch_2.nim b/challenge-257/archargelod/nim/ch_2.nim
new file mode 100755
index 0000000000..a8b112a365
--- /dev/null
+++ b/challenge-257/archargelod/nim/ch_2.nim
@@ -0,0 +1,64 @@
+#!/usr/bin/env -S nim r -d:release --verbosity:0 --hints:off
+import std/[sequtils]
+
+proc isReducedRowEchelon(matrix: openarray[seq[int]]): bool =
+ var expectZeroes = false
+ var leadingIndexes: seq[int]
+
+ for row in matrix:
+ # 1.Rows that consist entirely of zeros are at the bottom of the matrix.
+ if expectZeroes:
+ if row.anyIt(it != 0):
+ return false
+ continue
+
+ for index, val in row:
+ if val == 0:
+ if index == row.high:
+ expectZeroes = true
+ continue
+
+ # 2.Leading 1s are on the right of leading 1s above them.
+ if val != 1 or (leadingIndexes.len > 0 and index <= leadingIndexes[^1]):
+ return false
+
+ leadingIndexes.add index
+ break
+
+ # 3.Each column that contains a leading 1 has zeros everywhere else in that column.
+ for leadRow, leadCol in leadingIndexes:
+ for row in 0 .. matrix.high:
+ if row == leadRow:
+ continue
+ if matrix[row][leadCol] != 0:
+ return false
+
+ true
+
+when isMainModule:
+ import std/unittest
+
+ const
+ TestMatrices = [
+ @[@[1, 1, 0], @[0, 1, 0], @[0, 0, 0]],
+ @[@[0, 1, -2, 0, 1], @[0, 0, 0, 1, 3], @[0, 0, 0, 0, 0], @[0, 0, 0, 0, 0]],
+ @[@[1, 0, 0, 4], @[0, 1, 0, 7], @[0, 0, 1, -1]],
+ @[@[0, 1, -2, 0, 1], @[0, 0, 0, 0, 0], @[0, 0, 0, 1, 3], @[0, 0, 0, 0, 0]],
+ @[@[0, 1, 0], @[1, 0, 0], @[0, 0, 0]],
+ @[@[4, 0, 0, 0], @[0, 1, 0, 7], @[0, 0, 1, -1]]
+ ]
+ Expected = [false, true, true, false, false, false]
+
+ suite "Reduced Row Echelon":
+ test "Example 1":
+ check TestMatrices[0].isReducedRowEchelon() == Expected[0]
+ test "Example 2":
+ check TestMatrices[1].isReducedRowEchelon() == Expected[1]
+ test "Example 3":
+ check TestMatrices[2].isReducedRowEchelon() == Expected[2]
+ test "Example 4":
+ check TestMatrices[3].isReducedRowEchelon() == Expected[3]
+ test "Example 5":
+ check TestMatrices[4].isReducedRowEchelon() == Expected[4]
+ test "Example 6":
+ check TestMatrices[5].isReducedRowEchelon() == Expected[5]
diff --git a/challenge-257/athanasius/perl/ch-1.pl b/challenge-257/athanasius/perl/ch-1.pl
new file mode 100644
index 0000000000..9be329e6ae
--- /dev/null
+++ b/challenge-257/athanasius/perl/ch-1.pl
@@ -0,0 +1,177 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 257
+=========================
+
+TASK #1
+-------
+*Smaller than Current*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of integers, @ints.
+
+Write a script to find out how many integers are smaller than current i.e.
+foreach ints[i], count ints[j] < ints[i] where i != j.
+
+Example 1
+
+ Input: @ints = (5, 2, 1, 6)
+ Output: (2, 1, 0, 3)
+
+ For $ints[0] = 5, there are two integers (2,1) smaller than 5.
+ For $ints[1] = 2, there is one integer (1) smaller than 2.
+ For $ints[2] = 1, there is none integer smaller than 1.
+ For $ints[3] = 6, there are three integers (5,2,1) smaller than 6.
+
+Example 2
+
+ Input: @ints = (1, 2, 0, 3)
+ Output: (1, 2, 0, 3)
+
+Example 3
+
+ Input: @ints = (0, 1)
+ Output: (0, 1)
+
+Example 4
+
+ Input: @ints = (9, 4, 9, 2)
+ Output: (2, 1, 2, 0)
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2024 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=comment
+
+Interface
+---------
+If no command-line arguments are given, the test suite is run.
+
+=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 array of integers
+END
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 257, Task #1: Smaller than Current (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] );
+ }
+
+ printf "Input: \@ints = (%s)\n", join ', ', @ints;
+
+ my $counts = count_smaller_than_current( \@ints );
+
+ printf "Output: (%s)\n", join ', ', @$counts;
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub count_smaller_than_current
+#-------------------------------------------------------------------------------
+{
+ my ($ints) = @_;
+ my @counts;
+
+ for my $i (0 .. $#$ints)
+ {
+ my $count = 0;
+
+ for my $j (0 .. $#$ints)
+ {
+ next if $i == $j;
+
+ ++$count if $ints->[ $j ] < $ints->[ $i ];
+ }
+
+ push @counts, $count;
+ }
+
+ return \@counts;
+}
+
+#-------------------------------------------------------------------------------
+sub run_tests
+#-------------------------------------------------------------------------------
+{
+ print "Running the test suite\n";
+
+ while (my $line = <DATA>)
+ {
+ chomp $line;
+
+ my ($test_name, $int_str, $exp_str) = split / \| /x, $line;
+
+ for ($test_name, $int_str, $exp_str)
+ {
+ s/ ^ \s+ //x;
+ s/ \s+ $ //x;
+ }
+
+ my @ints = split / \s+ /x, $int_str;
+ my @exp = split / \s+ /x, $exp_str;
+ my $counts = count_smaller_than_current( \@ints );
+
+ is_deeply $counts, \@exp, $test_name;
+ }
+
+ done_testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+################################################################################
+
+__DATA__
+Example 1| 5 2 1 6|2 1 0 3
+Example 2| 1 2 0 3|1 2 0 3
+Example 3| 0 1 |0 1
+Example 4| 9 4 9 2|2 1 2 0
+Negatives|-2 -2 -1 |0 0 2
diff --git a/challenge-257/athanasius/perl/ch-2.pl b/challenge-257/athanasius/perl/ch-2.pl
new file mode 100644
index 0000000000..bb16d5aaf9
--- /dev/null
+++ b/challenge-257/athanasius/perl/ch-2.pl
@@ -0,0 +1,410 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 257
+=========================
+
+TASK #2
+-------
+*Reduced Row Echelon*
+
+Submitted by: Ali Moradi
+
+Given a matrix M, check whether the matrix is in reduced row echelon form.
+
+A matrix must have the following properties to be in reduced row echelon form:
+
+ 1. If a row does not consist entirely of zeros, then the first
+ nonzero number in the row is a 1. We call this the leading 1.
+ 2. If there are any rows that consist entirely of zeros, then
+ they are grouped together at the bottom of the matrix.
+ 3. In any two successive rows that do not consist entirely of zeros,
+ the leading 1 in the lower row occurs farther to the right than
+ the leading 1 in the higher row.
+ 4. Each column that contains a leading 1 has zeros everywhere else
+ in that column.
+
+For example:
+
+ [
+ [1,0,0,1],
+ [0,1,0,2],
+ [0,0,1,3]
+ ]
+
+The above matrix is in reduced row echelon form since the first nonzero number
+in each row is a 1, leading 1s in each successive row are farther to the right,
+and above and below each leading 1 there are only zeros.
+
+For more information check out this wikipedia
+[https://en.wikipedia.org/wiki/Row_echelon_form|article].
+
+Example 1
+
+ Input: $M = [
+ [1, 1, 0],
+ [0, 1, 0],
+ [0, 0, 0]
+ ]
+ Output: 0
+
+Example 2
+
+ Input: $M = [
+ [0, 1,-2, 0, 1],
+ [0, 0, 0, 1, 3],
+ [0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0]
+ ]
+ Output: 1
+
+Example 3
+
+ Input: $M = [
+ [1, 0, 0, 4],
+ [0, 1, 0, 7],
+ [0, 0, 1,-1]
+ ]
+ Output: 1
+
+Example 4
+
+ Input: $M = [
+ [0, 1,-2, 0, 1],
+ [0, 0, 0, 0, 0],
+ [0, 0, 0, 1, 3],
+ [0, 0, 0, 0, 0]
+ ]
+ Output: 0
+
+Example 5
+
+ Input: $M = [
+ [0, 1, 0],
+ [1, 0, 0],
+ [0, 0, 0]
+ ]
+ Output: 0
+
+Example 6
+
+ Input: $M = [
+ [4, 0, 0, 0],
+ [0, 1, 0, 7],
+ [0, 0, 1,-1]
+ ]
+ Output: 0
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2024 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=comment
+
+Interface
+---------
+1. If no command-line arguments are given, the test suite is run. Otherwise:
+2. The input matrix M is entered on the command-line as a non-empty list of
+ strings (the matrix rows) containing elements separated by whitespace. For
+ example, the matrix:
+
+ [ 1 1 0 ]
+ [ 0 1 0 ]
+ [ 0 0 0 ]
+
+ is entered as: >raku ch-2.raku "1 1 0" "0 1 0" "0 0 1"
+
+Assumptions
+-----------
+1. The input matrix M is an integer matrix.
+2. M is not an empty matrix.
+
+Note
+----
+Matrix-handling code is adapted from the solution to Task 2 for Week 248.
+
+=cut
+#===============================================================================
+
+use v5.32.1; # Enables strictures
+use warnings;
+use Const::Fast;
+use Regexp::Common qw( number );
+use Test::More;
+use enum qw( AllZeros LeadingOne Other );
+
+const my $USAGE => <<END;
+Usage:
+ perl $0 [<M> ...]
+ perl $0
+
+ [<M> ...] A non-empty integer matrix
+END
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 257, Task #2: Reduced Row Echelon (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ if (scalar @ARGV == 0)
+ {
+ run_tests();
+ }
+ else
+ {
+ my $matrix = parse_matrix( \@ARGV );
+
+ print_matrix( 'Input: $M = ', $matrix );
+
+ printf "Output: %d\n", is_reduced_row_echelon( $matrix );
+ }
+}
+
+#-------------------------------------------------------------------------------
+sub is_reduced_row_echelon
+#-------------------------------------------------------------------------------
+{
+ my ($matrix) = @_;
+
+ # Test matrix properties 1 and 2:
+ # 1. If a row does not consist entirely of zeros, then the first nonzero
+ # number in the row is a 1. We call this the leading 1.
+ # 2. If there are any rows that consist entirely of zeros, then they are
+ # grouped together at the bottom of the matrix.
+
+ my $row_types = classify_rows( $matrix );
+ my $all_zeros = 0;
+
+ for my $type (@$row_types)
+ {
+ if ($type == AllZeros)
+ {
+ $all_zeros = 1;
+ }
+ elsif ($type == LeadingOne)
+ {
+ return 0 if $all_zeros; # Requirement 2
+ }
+ else
+ {
+ return 0; # Requirement 1
+ }
+ }
+
+ # Test matrix properties 3 and 4:
+ # 3. In any two successive rows that do not consist entirely of zeros, the
+ # leading 1 in the lower row occurs farther to the right than the leading
+ # 1 in the higher row.
+ # 4. Each column that contains a leading 1 has zeros everywhere else in that
+ # column.
+
+ return check_leading_ones( $matrix, $row_types );
+}
+
+#-------------------------------------------------------------------------------
+sub classify_rows
+#-------------------------------------------------------------------------------
+{
+ my ($matrix) = @_;
+ my $width = scalar @{ $matrix->[ 0 ] };
+ my @row_types;
+
+ L_OUTER:
+ for my $r (0 .. $#$matrix)
+ {
+ my $row = $matrix->[ $r ];
+
+ for my $c (0 .. $width - 1)
+ {
+ my $element = $row->[ $c ];
+
+ if ($element == 1)
+ {
+ push @row_types, LeadingOne;
+ next L_OUTER;
+ }
+ elsif ($element != 0)
+ {
+ push @row_types, Other;
+ next L_OUTER;
+ }
+ }
+
+ push @row_types, AllZeros;
+ }
+
+ return \@row_types;
+}
+
+#-------------------------------------------------------------------------------
+sub check_leading_ones
+#-------------------------------------------------------------------------------
+{
+ my ($matrix, $row_t) = @_;
+ my $width = scalar @{ $matrix->[ 0 ] };
+ my $last_one = -1;
+
+ for my $r (0 .. $#$matrix)
+ {
+ last if $row_t->[ $r ] == AllZeros;
+
+ my $row = $matrix->[ $r ];
+
+ for my $c (0 .. $width - 1)
+ {
+ my $element = $row->[ $c ];
+
+ if ($element == 1)
+ {
+ return 0 unless $c > $last_one; # Test Requirement 3
+
+ $last_one = $c;
+
+ for my $rr (0 .. $#$matrix) # Test Requirement 4
+ {
+ return 0 unless $rr == $r || $matrix->[ $rr ][ $c ] == 0;
+ }
+
+ last;
+ }
+ }
+ }
+
+ return 1;
+}
+
+#-------------------------------------------------------------------------------
+sub parse_matrix
+#-------------------------------------------------------------------------------
+{
+ my ($M) = @_;
+ my (@matrix, $num_cols);
+
+ for my $row_str (@$M)
+ {
+ my @row;
+
+ for my $elem (grep { / \S /x } split / \s+ /x, $row_str)
+ {
+ if ($elem =~ / ^ $RE{num}{int} $ /x)
+ {
+ push @row, $elem;
+ }
+ else
+ {
+ error( qq[Element "$elem" is not a valid integer] );
+ }
+ }
+
+ push @matrix, \@row;
+
+ if (defined $num_cols)
+ {
+ scalar @row == $num_cols
+ or error( 'The input matrix is not rectangular' );
+ }
+ else
+ {
+ $num_cols = scalar @row;
+ $num_cols > 0 or error( 'Empty row' );
+ }
+ }
+
+ return \@matrix;
+}
+
+#-------------------------------------------------------------------------------
+sub print_matrix
+#-------------------------------------------------------------------------------
+{
+ my ($prefix, $matrix) = @_;
+ my $tab = ' ' x length $prefix;
+ my @width = (1) x scalar @{ $matrix->[ 0 ] };
+
+ for my $row (@$matrix)
+ {
+ for my $i (0 .. $#$row)
+ {
+ my $w = length $row->[ $i ];
+
+ $width[ $i ] = $w if $w > $width[ $i ];
+ }
+ }
+
+ print "$prefix\[\n";
+
+ for my $row (@$matrix)
+ {
+ my @row_str;
+
+ for my $i (0 .. $#$row)
+ {
+ push @row_str, sprintf '%*d', $width[ $i ], $row->[ $i ];
+ }
+
+ printf "%s [%s]\n", $tab, join ', ', @row_str;
+ }
+
+ print "$tab]\n";
+}
+
+#-------------------------------------------------------------------------------
+sub run_tests
+#-------------------------------------------------------------------------------
+{
+ print "Running the test suite\n";
+
+ while (my $line = <DATA>)
+ {
+ chomp $line;
+
+ my ($test_name, $matrix_str, $expected) = split / \| /x, $line;
+
+ for ($test_name, $matrix_str, $expected)
+ {
+ s/ ^ \s+ //x;
+ s/ \s+ $ //x;
+ }
+
+ my @M = split / \; /x, $matrix_str;
+ my $matrix = parse_matrix( \@M );
+ my $is_rre = is_reduced_row_echelon( $matrix );
+
+ is $is_rre, $expected, $test_name;
+ }
+
+ done_testing;
+}
+
+#-------------------------------------------------------------------------------
+sub error
+#-------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+################################################################################
+
+__DATA__
+Example 0|1 0 0 1 ; 0 1 0 2 ; 0 0 1 3 |1
+Example 1|1 1 0 ; 0 1 0 ; 0 0 0 |0
+Example 2|0 1 -2 0 1; 0 0 0 1 3; 0 0 0 0 0; 0 0 0 0 0|1
+Example 3|1 0 0 4 ; 0 1 0 7 ; 0 0 1 -1 |1
+Example 4|0 1 -2 0 1; 0 0 0 0 0; 0 0 0 1 3; 0 0 0 0 0|0
+Example 5|0 1 0 ; 1 0 0 ; 0 0 0 |0
+Example 6|4 0 0 0 ; 0 1 0 7 ; 0 0 1 -1 |0
diff --git a/challenge-257/athanasius/raku/ch-1.raku b/challenge-257/athanasius/raku/ch-1.raku
new file mode 100644
index 0000000000..21c615c9d8
--- /dev/null
+++ b/challenge-257/athanasius/raku/ch-1.raku
@@ -0,0 +1,178 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 257
+=========================
+
+TASK #1
+-------
+*Smaller than Current*
+
+Submitted by: Mohammad Sajid Anwar
+
+You are given an array of integers, @ints.
+
+Write a script to find out how many integers are smaller than current i.e.
+foreach ints[i], count ints[j] < ints[i] where i != j.
+
+Example 1
+
+ Input: @ints = (5, 2, 1, 6)
+ Output: (2, 1, 0, 3)
+
+ For $ints[0] = 5, there are two integers (2,1) smaller than 5.
+ For $ints[1] = 2, there is one integer (1) smaller than 2.
+ For $ints[2] = 1, there is none integer smaller than 1.
+ For $ints[3] = 6, there are three integers (5,2,1) smaller than 6.
+
+Example 2
+
+ Input: @ints = (1, 2, 0, 3)
+ Output: (1, 2, 0, 3)
+
+Example 3
+
+ Input: @ints = (0, 1)
+ Output: (0, 1)
+
+Example 4
+
+ Input: @ints = (9, 4, 9, 2)
+ Output: (2, 1, 2, 0)
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2024 PerlMonk Athanasius #
+#--------------------------------------#
+
+#===============================================================================
+=begin comment
+
+Interface
+---------
+If no command-line arguments are given, the test suite is run.
+
+=end comment
+#===============================================================================
+
+use Test;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 257, Task #1: Smaller than Current (Raku)\n".put;
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ #| A non-empty array of integers
+
+ *@ints where { .elems > 0 && .all ~~ Int:D }
+)
+#===============================================================================
+{
+ "Input: \@ints = (%s)\n".printf: @ints.join: ', ';
+
+ my UInt @counts = count-smaller-than-current( @ints );
+
+ "Output: (%s)\n".printf: @counts.join: ', ';
+}
+
+#===============================================================================
+multi sub MAIN() # No input: run the test suite
+#===============================================================================
+{
+ run-tests();
+}
+
+#-------------------------------------------------------------------------------
+sub count-smaller-than-current( List:D[Int:D] $ints --> List:D[UInts:D] )
+#-------------------------------------------------------------------------------
+{
+ my UInt @counts;
+
+ for 0 .. $ints.end -> UInt $i
+ {
+ my UInt $count = 0;
+
+ for 0 .. $ints.end -> UInt $j
+ {
+ next if $i == $j;
+
+ ++$count if $ints[ $j ] < $ints[ $i ];
+ }
+
+ @counts.push: $count;
+ }
+
+ return @counts;
+}
+
+#-------------------------------------------------------------------------------
+sub run-tests()
+#-------------------------------------------------------------------------------
+{
+ 'Running the test suite'.put;
+
+ for test-data.lines -> Str $line
+ {
+ my Str ($test-name, $int-str, $exp-str) = $line.split: / \| /;
+
+ for $test-name, $int-str, $exp-str
+ {
+ s/ ^ \s+ //;
+ s/ \s+ $ //;
+ }
+
+ my Int @ints = ($int-str.split: / \s+ /, :skip-empty).map: { .Int };
+ my UInt @exp = ($exp-str.split: / \s+ /, :skip-empty).map: { .Int };
+ my UInt @counts = count-smaller-than-current( @ints );
+
+ is-deeply @counts, @exp, $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| 5 2 1 6|2 1 0 3
+ Example 2| 1 2 0 3|1 2 0 3
+ Example 3| 0 1 |0 1
+ Example 4| 9 4 9 2|2 1 2 0
+ Negatives|-2 -2 -1 |0 0 2
+ END
+}
+
+################################################################################
diff --git a/challenge-257/athanasius/raku/ch-2.raku b/challenge-257/athanasius/raku/ch-2.raku
new file mode 100644
index 0000000000..4bb6a71228
--- /dev/null
+++ b/challenge-257/athanasius/raku/ch-2.raku
@@ -0,0 +1,410 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 257
+=========================
+
+TASK #2
+-------
+*Reduced Row Echelon*
+
+Submitted by: Ali Moradi
+
+Given a matrix M, check whether the matrix is in reduced row echelon form.
+
+A matrix must have the following properties to be in reduced row echelon form:
+
+ 1. If a row does not consist entirely of zeros, then the first
+ nonzero number in the row is a 1. We call this the leading 1.
+ 2. If there are any rows that consist entirely of zeros, then
+ they are grouped together at the bottom of the matrix.
+ 3. In any two successive rows that do not consist entirely of zeros,
+ the leading 1 in the lower row occurs farther to the right than
+ the leading 1 in the higher row.
+ 4. Each column that contains a leading 1 has zeros everywhere else
+ in that column.
+
+For example:
+
+ [
+ [1,0,0,1],
+ [0,1,0,2],
+ [0,0,1,3]
+ ]
+
+The above matrix is in reduced row echelon form since the first nonzero number
+in each row is a 1, leading 1s in each successive row are farther to the right,
+and above and below each leading 1 there are only zeros.
+
+For more information check out this wikipedia
+[https://en.wikipedia.org/wiki/Row_echelon_form|article].
+
+Example 1
+
+ Input: $M = [
+ [1, 1, 0],
+ [0, 1, 0],
+ [0, 0, 0]
+ ]
+ Output: 0
+
+Example 2
+
+ Input: $M = [
+ [0, 1,-2, 0, 1],
+ [0, 0, 0, 1, 3],
+ [0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0]
+ ]
+ Output: 1
+
+Example 3
+
+ Input: $M = [
+ [1, 0, 0, 4],
+ [0, 1, 0, 7],
+ [0, 0, 1,-1]
+ ]
+ Output: 1
+
+Example 4
+
+ Input: $M = [
+ [0, 1,-2, 0, 1],
+ [0, 0, 0, 0, 0],
+ [0, 0, 0, 1, 3],
+ [0, 0, 0, 0, 0]
+ ]
+ Output: 0
+
+Example 5
+
+ Input: $M = [
+ [0, 1, 0],
+ [1, 0, 0],
+ [0, 0, 0]
+ ]
+ Output: 0
+
+Example 6
+
+ Input: $M = [
+ [4, 0, 0, 0],
+ [0, 1, 0, 7],
+ [0, 0, 1,-1]
+ ]
+ Output: 0
+
+=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 matrix M is entered on the command-line as a non-empty list of
+ strings (the matrix rows) containing elements separated by whitespace. For
+ example, the matrix:
+
+ [ 1 1 0 ]
+ [ 0 1 0 ]
+ [ 0 0 0 ]
+
+ is entered as: >raku ch-2.raku "1 1 0" "0 1 0" "0 0 1"
+
+Assumptions
+-----------
+1. The input matrix M is an integer matrix.
+2. M is not an empty matrix.
+
+Note
+----
+Matrix-handling code is adapted from the solution to Task 2 for Week 248.
+
+=end comment
+#===============================================================================
+
+use Test;
+
+enum RowType < AllZeros LeadingOne Other >;
+subset Matrix of Array where * ~~ Array[Array[Int]];
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 257, Task #2: Reduced Row Echelon (Raku)\n".put;
+}
+
+#===============================================================================
+multi sub MAIN
+(
+ *@M where { .all ~~ Str:D && .elems > 0 } #= A non-empty integer matrix
+)
+#===============================================================================
+{
+ my Matrix $matrix = parse-matrix( @M );
+
+ print-matrix( 'Input: $M = ', $matrix );
+
+ my Bool $is-rre = is-reduced-row-echelon( $matrix );
+
+ "Output: %d\n".printf: $is-rre ?? 1 !! 0;
+}
+
+#====================