by Arne Sommer

# The Primorial Soup - a Raku Product

 Published 25. June 2022.

This is my response to The Weekly Challenge #170.

## Challenge #170.1: Primorial Numbers

Write a script to generate first `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); #  my \$primes := (1 .. *).grep( *.is-prime ); #  my \$primorial := gather #  { take my \$prev = 1; #  for \$primes -> \$prime #  { take \$prev = \$prev * \$prime; # [5a] } } say \$primorial[^\$count].join(", "); #  ```

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

 The Prime sequence.

 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`.

 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.

 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.

 (Compute and) print the required number of values.

Running it:

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

Looking good.

## Challenge #170.2: Kronecker Product

You are given 2 matrices.

Write a script to implement `Kronecker Product` on the given 2 matrices.

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"`.

File: kronecker-product ```#! /usr/bin/env raku unit sub MAIN (Str \$A, Str \$B); my @A = \$A.split("|")>>.words>>.List; #  my @B = \$B.split("|")>>.words>>.List; #  my \$A-rows = @A.elems; #  my \$A-cols = @A.elems; #  my \$B-rows = @B.elems; #  # my \$B-cols = @B.elems; # [2a] my @C; #  for ^\$A-rows -> \$Ar #  { for ^\$B-rows -> \$Br #  { my @row; #  for ^\$A-cols -> \$Ac #  { @row.append: (@B[\$Br]).map({ \$_ * @A[\$Ar][\$Ac] }); #  } @C.push: @row; #  } } @C.map: *.say; #  ```

 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.

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

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

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

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

 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.

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

 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.

 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`.

 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.