### Perl Weekly Challenge: Week 158

Congratulations and thanks to Mohammed for 3 years of the weekly challenge.

#### Challenge 1:

**Additive Primes**

Write a script to find out all

`Additive Primes <= 100`

.Additive primes are prime numbers for which the sum of their decimal digits are also primes.

##### Output

```
2, 3, 5, 7, 11, 23, 29, 41, 43, 47, 61, 67, 83, 89
```

This problem can be solved as a one-liner. First we take the range, 2 to 100. (1 is not a prime so we can safely
ignore it.) Then we find the prime numbers in that range by `.grep()`

ing with `.is-prime()`

. These prime numbers are filtered
yet again by splitting them into individual digits with `.comb()`

and summing the digits with `[+]`

and checking if that number
is prime. The result of all this is a list of additive primes which is joined up with commas via `.join()`

and printed.

```
(2 .. 100).grep({ .is-prime }).grep({ ([+] .comb).is-prime }).join(q{, }).say;
```

Alas we cannot be quite so succint with Perl due to a lack of `[+]`

and `.is-prime`

. But as this comes up a lot in these challenges
I have long since developed `sum()`

and `isPrime()`

functions and I used them again this week. With these, the core of the solution
can be expressed in one line like this:

```
say join q{, }, grep { isPrime(sum([split //])) } grep { isPrime($_) } 2 .. 100;
```

It's just like the Raku solution except the order of operations is right to left instead of left to right.

#### Challenge 2:

**First Series Cuban Primes**

Write a script to compute first series `Cuban Primes <= 1000`

. Please refer wikipedia page for more informations.

##### Output

```
7, 19, 37, 61, 127, 271, 331, 397, 547, 631, 919.
```

Here is the Perl solution:

The Wikepedia page given has a formula for calculating these types of primes in terms of x and y. So first we create a variable to hold the current value of y starting from 1. x is always going to be y + 1 so it can be calculated in terms of `$y`

. We also
create a list, `@cubans`

to hold the results.

```
my $y = 1;
my @cubans;
```

Then we enter an infinite loop in which to calculate Cuban primes.

```
while(1) {
```

A simple transposition of the formula on the Wikipedia page could be:

```
my $x = $y + 1;
my $p = (($x ** 3) - ($y ** 3)) / ($x - $y);
```

One might notice that x - y is always 1 so the calculation can be simplified to

```
my $p - ($x ** 3) - ($y ** 3);
```

However the page also notes that this formula can be simplified even further to 3y^{2} + 3y + 1 so
I have coded it like this:

```
my $p = 3 * $y ** 2 + 3 * $y + 1;
```

This way also has the advantage of removing the need for representing x.

If the value calculated for `$p`

is greater than 1000, we can stop and break out of the loop.

```
if ($p > 1000) {
last;
}
```

If it isn't and `$p`

is a prime number, we add it to the results.

```
if (isPrime($p)) {
push @cubans, $p;
}
```

We increment `$y`

and do the next iteration of the loop.

```
$y++;
}
```

Finally, we join all the results with commas and print them out.

```
say join q{, }, @cubans;
```

For Raku, I normally would have followed a similar method as with Perl but I remembered that it has a nifty feature, `gather`

and `take`

which I should be using more of. As I understand it, `gather`

executes a block asynchronously in a coroutine from which results are emitted by `take`

. So it is more efficient and potentially faster than the traditional approach. Another benefit is that we don't need an intermediate list to store the results; we can directly `.join()`

and `.say()`

the output of the `gather`

block.

```
my $y = 1;
gather {
loop {
my $p = 3 * $y ** 2 + 3 * $y + 1;
if $p > 1000 {
last;
}
if ($p.is-prime) {
take $p;
}
$y++;
}
}.join(q{, }).say;
```