A Raku Product

This is my response to The Weekly Challenge #170.

Write a script to generate first

Primorial numbers are those formed by multiplying successive prime numbers.

For Example:

`10 Primorial Numbers`

.
Primorial numbers are those formed by multiplying successive prime numbers.

For Example:

P(0) = 1 (1)
P(1) = 2 (1x2)
P(2) = 6 (1x2×3)
P(3) = 30 (1x2×3×5)
P(4) = 210 (1x2×3×5×7)

Note that 1 is not a prime, so the
sequence should *arguably* start with `P(1) = 2`

.
Wikipedia supports both views.

File: primorial-numbers

#! /usr/bin/env raku
unit sub MAIN (Int $count where $count > 0 = 10); # [1]
my $primes := (1 .. *).grep( *.is-prime ); # [2]
my $primorial := gather # [3]
{
take my $prev = 1; # [4]
for $primes -> $prime # [5]
{
take $prev = $prev * $prime; # [5a]
}
}
say $primorial[^$count].join(", "); # [6]

[1] The number of elements to print, with 10 as default.

[2] The Prime sequence.

[3] Using `gather`

/`take`

to set up the
main (Primorial) sequence is ideal here.

See my Raku Gather,
I Take article or
docs.raku.org/syntax/gather take for more information about
`gather`

/`take`

.

[4] This is the very first value in the sequence, and must be hard coded as it is not
a prime. Note the usage of the `$prev`

variable to hold the previous value
in sequence.

[5] Iterate over the primes. We get the new value in the sequence by multiplying the previous one with the next unused prime [5a]. Note the assignment.

[6] (Compute and) print the required number of values.

Running it:

$ ./primorial-numbers
1, 2, 6, 30, 210, 2310, 30030, 510510, 9699690, 223092870

Looking good.

You are given 2 matrices.

Write a script to implement

Write a script to implement

`Kronecker Product`

on the given 2 matrices.
For more information, please refer wikipedia page.

For Example:A = [ 1 2 ]
[ 3 4 ]
B = [ 5 6 ]
[ 7 8 ]
A x B = [ 1 x [ 5 6 ] 2 x [ 5 6 ] ]
[ [ 7 8 ] [ 7 8 ] ]
[ 3 x [ 5 6 ] 4 x [ 5 6 ] ]
[ [ 7 8 ] [ 7 8 ] ]
= [ 1x5 1x6 2x5 2x6 ]
[ 1x7 1x8 2x7 2x8 ]
[ 3x5 3x6 4x5 4x6 ]
[ 3x7 3x8 4x7 4x8 ]
= [ 5 6 10 12 ]
[ 7 8 14 16 ]
[ 15 18 20 24 ]
[ 21 24 28 32 ]

We need a way of specifying the matrices.
Spaces to separate the values, and vertical bars (`|`

) to separate the rows
seems reasonable. The example can be expressed like this:
`"1 2 | 3 4"`

and `"5 6 | 7 8"`

.

#! /usr/bin/env raku
unit sub MAIN (Str $A, Str $B);
my @A = $A.split("|")>>.words>>.List; # [1]
my @B = $B.split("|")>>.words>>.List; # [1]
my $A-rows = @A.elems; # [2]
my $A-cols = @A[0].elems; # [2]
my $B-rows = @B.elems; # [2]
# my $B-cols = @B[0].elems; # [2a]
my @C; # [3]
for ^$A-rows -> $Ar # [4]
{
for ^$B-rows -> $Br # [5]
{
my @row; # [6]
for ^$A-cols -> $Ac # [7]
{
@row.append: (@B[$Br]).map({ $_ * @A[$Ar][$Ac] }); # [8]
}
@C.push: @row; # [9]
}
}
@C.map: *.say; # [10]

[1] Turn the the string into a two-dimentional array. The postfix `>>.List`

ensures that each row are evaluated up front, as we would have gotten (lazy) sequences
if not.

[2] We need these values in the loops, so here they are. Note that the last one [2a] is not needed.

[3] The result (also a matrix) will end up here.

[4] First we iterate over the rows in A (the indices).

[5] Each of the rows in A shall result in as many rows as in B, so we iterate over that one as well.

[6] This block is where we compute the actual rows (ending up in C), one at a time, so we set up a local variable here.

[7] Then we iterate over the columns in A. Each one will add to the row.

[8] Add (with `append`

, so that we get the values
appended one at a time) the partial data. We use `map`

to get the actual
values.

[9] Add the new row to C. Here we do want a new row, so
`push`

is appropriate.

See
docs.raku.org/routine/append
for more information about `append`

.

See
docs.raku.org/routine/push
for more information about `push`

.

[10] Print the matrix, one sublist (i.e. matrix row) at a time.

Running it:

$ ./kronecker-product "1 2 | 3 4" "5 6 | 7 8"
[5 6 10 12]
[7 8 14 16]
[15 18 20 24]
[21 24 28 32]

Looking good. (Except for the missing tabulation and extra spaces used in the challenge, but that is a minor issue.)

And that's it.