fibonacci_number_fast.pl 921 B

123456789101112131415161718192021222324252627282930313233
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 19 June 2018
  4. # https://github.com/trizen
  5. # An efficient algorithm for computing the nth-Fibonacci number.
  6. # See also:
  7. # https://github.com/trizen/perl-scripts/blob/master/Math/modular_fibonacci_cassini.pl
  8. # https://github.com/trizen/perl-scripts/blob/master/Math/modular_fibonacci_cassini_fast.pl
  9. use 5.020;
  10. use warnings;
  11. use experimental qw(signatures);
  12. use Math::AnyNum qw(:overload ilog2 getbit);
  13. sub fibonacci_number($n) {
  14. my ($f, $g) = (0, 1);
  15. my ($a, $b) = (0, 1);
  16. foreach my $k (0 .. ilog2($n)||0) {
  17. ($f, $g) = ($f*$a + $g*$b, $f*$b + $g*($a+$b)) if getbit($n, $k);
  18. ($a, $b) = ($a*$a + $b*$b, $a*$b + $b*($a+$b));
  19. }
  20. return $f;
  21. }
  22. say fibonacci_number(100); #=> 354224848179261915075
  23. say join(' ', map { fibonacci_number($_) } 0 .. 15); #=> 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610