Same Element
with Raku

by Arne Sommer

Same Element with Raku

[406] Published 9. July 2026.

This is my response to The Weekly Challenge #381.

#381.1 Same Row Column You are given an n x n matrix containing integers from 1 to n.

Write a script to find if every row and every column contains all the integers from 1 to n.

Example 1:
Input: @matrix = ([1, 2, 3, 4],
                  [2, 3, 4, 1],
                  [3, 4, 1, 2],
                  [4, 1, 2, 3],)
Output: true
Example 2:
Input: @matrix = ([1])
Output: true
Example 3:
Input: @matrix = ([1, 2, 5],
                  [5, 1, 2],
                  [2, 5, 1],)
Output: false

Elements are out of range 1..3.
Example 4:
Input: @matrix = ([1, 2, 3],
                  [1, 2, 3],
                  [1, 2, 3],)
Output: false
Example 5:
Input: @matrix = ([1, 2, 3],
                  [3, 1, 2],
                  [3, 2, 1],)
Output: false

Note the use of my «matrix as a string» syntax in this program, see e.g. the default matrix in [3] or the examples. It was last used in «find-celebrity», the second part of Celebrity Representation, my response to challenge #361.

File: same-row-column
#! /usr/bin/env raku

unit sub MAIN ($string = "1 2 5 | 5 1 2 | 2 5 1",
               :v(:$verbose));

my $matrix = $string.split("|")>>.words>>.Numeric;
my $rows   = $matrix.elems;
my $cols   = $matrix[0].elems;
my @target = 1 .. $cols;

die "The rows must have the same size"
  unless [==] $matrix>>.elems;

die "The matrix must have the same number of rows and columns"
  unless $rows == $cols;

die "Must contain integers only"
  unless all($matrix[*;*]) ~~ Int;

if $verbose
{
  say ":Matrix: { $matrix.raku }";
  say ":Target: @target[]";
}

say same-row-column($matrix, @target);

sub same-row-column ($matrix, @target)
{
  for ^$cols -> $col
  {
    my @col      = $matrix[*;$col];
    my @col-sort = @col.sort;
    my $is-ok    = @col-sort eqv @target;

    say ":Column $col: @col[] is { $is-ok ?? "ok" !! "not ok" }"
      if $verbose;

    return False unless $is-ok;

    my @row      = $matrix[$col];
    my @row-sort = @row.sort;
       $is-ok    = @col-sort eqv @target;

    say ":Row $col: @row[] is { $is-ok ?? "ok" !! "not ok"}"
      if $verbose;

    return False unless $is-ok;
  }

  return True;
}

[3] A default matrix, in case the user does not supply one.

[6] Split the rows on the | and the individual row items on space(s). Coerce the whole shebang to numeric values (i.e. crash on non-numeric values).

[7] The number of rows.

[8] The number of columns, taken from the first row.

[9] An array containing the target values.

[11] Ensure that all the rows have the same size, with the Reduction Metaoperator [] with == as the operator.

See docs.raku.org/language/operators#Reduction_metaoperators for more information about the Reduction Metaoperator [].

[14] Ensure that the number of rows and columns are equal.

[17] Ensure that the matrix only contains integers.

Skipping this line, and replacing Numeric in [6] with int is a possibility, but it would (silently) truncate non-integer numeric values to integers. You really do not want that.

[26] Fire off the check.

[28] The procedure doing the check. Note that $verbose is a global variable, which is a bad (or lazy) design choice.

[30] Iterate over the column (and row) indices.

[32] Extract the column values.

[33] Sort those values, so that we can compare them.

[34] Compare the sorted values from the column with the target, using the eqv operator (as it works on data structures).

See docs.raku.org/routine/eqv for more information about eqv.

[39] Report failure (False) if they do not match up.

[41-48] The same for the row data.

[51] Failure to fail (in any of the [39] and [48] in the loop) means success.

Running it:

$ ./same-row-column "1 2 3 4 | 2 3 4 1 | 3 4 1 2 | 4 1 2 3"
True

$ ./same-row-column "1"
True

$ ./same-row-column "1 2 5 | 5 1 2 | 2 5 1"
False

$ ./same-row-column "1 2 3 | 1 2 3 | 1 2 3"
False

$ ./same-row-column "1 2 3 | 3 1 2 | 3 2 1"
False

Looking good.

With verbose mode:

$ ./same-row-column -v "1 2 3 4 | 2 3 4 1 | 3 4 1 2 | 4 1 2 3"
:Matrix: $([1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2], [4, 1, 2, 3])
:Target: 1 2 3 4
:Column 0: 1 2 3 4 is ok
:Column 0: 1 2 3 4 is OK
:Row 0: 1 2 3 4 is ok
:Column 1: 2 3 4 1 is ok
:Column 1: 2 3 4 1 is OK
:Row 1: 2 3 4 1 is ok
:Column 2: 3 4 1 2 is ok
:Column 2: 3 4 1 2 is OK
:Row 2: 3 4 1 2 is ok
:Column 3: 4 1 2 3 is ok
:Column 3: 4 1 2 3 is OK
:Row 3: 4 1 2 3 is ok
True


$ ./same-row-column -v "1"
:Matrix: $([1],)
:Target: 1
:Column 0: 1 is ok
:Column 0: 1 is OK
:Row 0: 1 is ok
True

$ ./same-row-column -v "1 2 5 | 5 1 2 | 2 5 1"
:Matrix: $([1, 2, 5], [5, 1, 2], [2, 5, 1])
:Target: 1 2 3
:Column 0: 1 5 2 is not ok
False

$ ./same-row-column -v "1 2 3 | 1 2 3 | 1 2 3"
:Matrix: $([1, 2, 3], [1, 2, 3], [1, 2, 3])
:Target: 1 2 3
:Column 0: 1 1 1 is not ok
False

$ ./same-row-column -v "1 2 3 | 3 1 2 | 3 2 1"
:Matrix: $([1, 2, 3], [3, 1, 2], [3, 2, 1])
:Target: 1 2 3
:Column 0: 1 3 3 is not ok
False

#381.2 Smaller Greater Element You are given an array of integers.

Write a script to find the number of elements that have both a strictly smaller and greater element in the given array.

Example 1:
Input: @int = (2,4)
Output: 0

Not enough elements in the array.
Example 2:
Input: @int = (1, 1, 1, 1)
Output: 0
Example 3:
Input: @int = (1, 1, 4, 8, 12, 12)
Output: 2

The elements are 4 and 8.
Example 4:
Input: @int = (3, 6, 6, 9)
Output: 2

Both instances of 6.
Example 5:
Input: @int = (0, -5, 10, -2, 4)
Output: 3

The elements are 0, -2, and 4.
File: /smaller-greater-element
#! /usr/bin/env raku

unit sub MAIN (*@ints where @ints.elems > 0 && all(@ints) ~~ Int,
                :v(:$verbose))
{
  my $min      = @ints.min;
  my $max      = @ints.max;
  my @strictly = @ints.grep( $min < * < $max );

  if $verbose
  {
    say ":Min: $min";
    say ":Max: $max";
    say ":Strictly: @strictly[]";
  }

  say @strictly.elems;
}

[3] At least one element, and all of them must be integers.

[6] The minimum value with min.

See docs.raku.org/routine/min for more information about min.

[7] The maximum value with max.

See docs.raku.org/routine/max for more information about max.

[8] The «strictly» values, i.e. values greater than $min and smaller than $max. We use grep to get them.

See docs.raku.org/routine/grep for more information about grep.

[17] Print the number of «strictly» values.

Running it:

$ ./smaller-greater-element 2 4
0
$ ./smaller-greater-element 1 1 1 1
0

$ ./smaller-greater-element 1 1 4 8 12 12
2

$ ./smaller-greater-element 3 6 6 9
2

$ ./smaller-greater-element 0 -5 10 -2 4
3

Looking good.

With verbose mode:

$ ./smaller-greater-element -v 2 4
0

$ ./smaller-greater-element -v 1 1 1 1
:Min: 1
:Max: 1
:Strictly: 
0

$ ./smaller-greater-element -v 1 1 4 8 12 12
:Min: 1
:Max: 12
:Strictly: 4 8
2

$ ./smaller-greater-element -v 3 6 6 9
:Min: 3
:Max: 9
:Strictly: 6 6
2

$ ./smaller-greater-element -v 0 -5 10 -2 4
:Min: -5
:Max: 10
:Strictly: 0 -2 4
3

And that's it.