pisano_periods.pl 979 B

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 11 October 2017
  4. # https://github.com/trizen
  5. # Algorithm for computing the Pisano numbers (period of Fibonacci numbers mod n), using the prime factorization of `n`.
  6. # See also:
  7. # https://oeis.org/A001175
  8. # https://en.wikipedia.org/wiki/Pisano_period
  9. use 5.020;
  10. use strict;
  11. use warnings;
  12. use experimental qw(signatures lexical_subs);
  13. use ntheory qw(addmod factor_exp lcm);
  14. sub pisano_period($mod) {
  15. my sub find_period($mod) {
  16. my ($x, $y) = (0, 1);
  17. for (my $n = 1 ; ; ++$n) {
  18. ($x, $y) = ($y, addmod($x, $y, $mod));
  19. if ($x == 0 and $y == 1) {
  20. return $n;
  21. }
  22. }
  23. }
  24. my @prime_powers = map { $_->[0]**$_->[1] } factor_exp($mod);
  25. my @power_periods = map { find_period($_) } @prime_powers;
  26. return lcm(@power_periods);
  27. }
  28. my $n = 5040;
  29. my $period = pisano_period($n);
  30. say "Pisano period for modulus $n is $period."; #=> 240