## Advent Calendar - December 9, 2022

Friday, Dec 9, 2022| Tags: Raku ### |   Day 8   |   Day 9   |   Day 10   |

The gift is presented by `Luca Ferrari`. Today he is talking about his solution to “The Weekly Challenge - 155”. This is re-produced for Advent Calendar 2022 from the original post by him.

It is sad that, after more than two years of me doing Raku, I still don’t have any production code project to work on. Therefore, in order to keep my coding and Raku-ing (is that a term?) knowdledge, I try to solve every Perl Weekly Challenge tasks.

## PWC 155 - Task 1

Not so hard: compute the `Fortunate numbers`, those numbers that sum with a pn give a prime number. Here, `pn` stands for the multiplication of all n prime numbers. The task added to find out all `first 8 unique Fortunate numbers`.

``````sub MAIN( Int \$limit where { \$limit > 0 } = 8 ) {
my @fortunate-numbers = lazy gather {
for 2 .. Inf {
my @pn = ( 1 .. \$_ ).grep: *.is-prime;
next if ! @pn;
for @pn.max + 1 .. Inf -> \$m {
take \$m and last if ( ( [*] @pn ) + \$m ).is-prime;
}
}
}

my @unique-fortunate-numbers;
my \$last-number = 0;
while ( @unique-fortunate-numbers.elems < \$limit ) {
my \$fortunate = @fortunate-numbers[ \$last-number++ ];
@unique-fortunate-numbers.push: \$fortunate if ! @unique-fortunate-numbers.grep: * ~~ \$fortunate;
}

@unique-fortunate-numbers[ 0 .. \$limit - 1 ].sort.join( "\n" ).say;
}
``````

The `@fortunate-numbers` is a lazy array computed by `means of @pn`, which is the list of all prime numbers up to a given number, and then a new loop is done to find out the smallest `\$m` number greater than any value in `@pn` that, when summed with the multiplication of all values in @pn gives a prime.

To find out only unique numbers, I loop again to build a `@unique-fortunate-numbers` array and stop the searching for as soon as the elements in the array are at the limit.

## PWC 155 - Task 2

`Pisano Period`: finding out the repetition of the sequence of Fibonacci when every element is modulo a given number.

``````sub MAIN( Int \$nth where { \$nth >= 3 } = 3,
Int \$accuracy where { \$accuracy > 1 } = 5,
Bool :\$verbose = False ) {

my @fibonacci = 0, 1, 1, 2, * + * ... *;
my @pisano    = @fibonacci.map: * % 3;

# with nth >= 3 the period is always even
my \$period = 2;

# build \$accuracy arrays to check
my @checking.push: @pisano[ ( 0 + \$period * \$_ ) .. ( \$period * ( \$_  + 1 ) ) - 1 ] for 1 .. \$accuracy;

# while the array are not all the same, grow them and recheck
while ( not [eqv] @checking ) {
\$period += 2;
@checking = ();
@checking.push: @pisano[ ( 0 + \$period * \$_ ) .. ( \$period * ( \$_  + 1 ) ) - 1 ] for 1 .. \$accuracy;
}

@checking.join( "\n" ).join( ',' ).say if \$verbose;
"Pisano period \$nth is \$period".say;

}
``````

The idea is to build a lazy sequence `@pisano` that `map`s every element of the Fibonacci’s serie `modulo 3` as asked. Since, when the modulo applied is greater or equal to 3, the period (i.e., the size of repeating part of the sequence) is always even, I start with a `\$period` of `2`. Then I extract a number of arrays of size `\$period` equal in number to `\$accuracy`, e.g., 5 arrays of size 2. Last, I check if the extracted array are all the same, i.e., are `eqv`. If they are, the `\$period` is found, otherwise I increase the period of a even value and do it again.

If you have any suggestion then please do share with us perlweeklychallenge@yahoo.com.

## SO WHAT DO YOU THINK ?

If you have any suggestions or ideas then please do share with us.