# ETOOBUSY ðŸš€ minimal blogging for the impatient

# PWC155 - Pisano Period

**TL;DR**

On with TASK #2 from The Weekly Challenge #155. Enjoy!

# The challenge

Write a script to find the period of the

`3rd Pisano Period`

.In number theory, the nth Pisano period, written as Ï€(n), is the period with which the sequence of Fibonacci numbers taken modulo n repeats.

The Fibonacci numbers are the numbers in the integer sequence:

`0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, ...`

For any integer n, the sequence of Fibonacci numbers F(i) taken modulo n is periodic. The Pisano period, denoted Ï€(n), is the value of the period of this sequence. For example, the sequence of Fibonacci numbers modulo 3 begins:

`0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, ...`

This sequence has period 8, so Ï€(3) = 8.

# The questions

Challenges lately are quite *tight* in their requirements that questions
are hard to think. I mean, if it were a more general question asking for
the $n$th number, I could have asked what the maximum value for $n$
would beâ€¦

I know itâ€™s 3, Iâ€™ll assume itâ€™s not that big ðŸ˜„

# The solution

Calculating the period by taking the remainder of the Fibonacci sequence is the same as calculating each new item in the sequence directly from the previously calculated reminders. In other terms, if we define:

\[x_n := \{v: v = x + k \cdot n, k \in \mathbb{Z}\}\]that is the usual definition of remainder class modulo $n$, then we have:

\[(x + y)_n = x_n + y_n\]In considering $x_n$, we can take *any* of the values $v$ in the class,
although usually the lowest non-negative value is used for simplicity.

In other terms, we can calculate the modulo operation as soon as we sum
two items, and forget about calculating the *original* Fibonacci
sequence.

This means that sequences MUST be periodic, because any time we end up with the same pair of consecutive values, the sequence is going to repeat. With only $n$ possible remainders, there are only $n^2$ possible pairs of consecutive values, so at a certain point we MUST hit a pair that we already saw.

Additional demonstrations show that itâ€™s OK to take the initial values in the sequence as the ones to look for periodicity, so we will concentrate on looking for $0_n$ followed by $1_n$. This is important because the periodic part might be preceded by some a-periodic head, but this is not the case here.

Letâ€™s look at the Perl code:

```
#!/usr/bin/env perl
use v5.24;
use warnings;
use experimental 'signatures';
no warnings 'experimental::signatures';
say pisano_period(shift // 3);
sub pisano_period ($n) {
my ($fl, $fh) = (0, 1 % $n);
my $pp = 0;
while ('necessary') {
($fl, $fh) = ($fh, ($fl + $fh) % $n);
++$pp;
return $pp if $fl == 0 && $fh == 1 % $n;
}
}
```

The astute reader will have noted that weâ€™re doing `1 % $n`

while
initializing the two Fibonacci state variables. This is because $n = 1$
is a valid input, and in *that* case the remainder is $0$, not $1$.

We might just as well written this:

```
sub pisano_period ($n) {
return 1 if $n == 1;
my ($fl, $fh) = (0, 1);
...
```

Which leads us to Raku, where `multi sub`

are a way to deal with
special cases:

```
#!/usr/bin/env raku
use v6;
sub MAIN (Int:D $n = 3) { put pisano-period($n) }
multi sub pisano-period (1) { return 1 }
multi sub pisano-period ($n) {
my ($fl, $fh) = 0, 1;
my $pp = 0;
loop {
($fl, $fh) = $fh, ($fl + $fh) % $n;
++$pp;
return $pp if $fl == 0 && $fh == 1;
}
}
```

Stay safe folks!

*Comments? Octodon, Twitter, GitHub, Reddit, or drop me a line!*