bnghtz

fibonacci_2pX_Ydigit.pl

Oct 5th, 2013
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 2.07 KB | None | 0 0
  1. #! /usr/bin/perl
  2. ###############################################################################
  3. #  $0 <exp> <digit>                                                           #
  4. #    gets the last <digit> digit from the <2^exp>th fibonacci number          #
  5. #    maximal exp    = 97   default exp    = 53                                #
  6. #    maximal digits =  9   default digits =  6                                #
  7. ###############################################################################
  8. use warnings;
  9. use strict;
  10.  
  11. ##### GET and CHECKING PARAMETERS
  12.  
  13. sub useage()
  14. {
  15.   warn "$0 exp digit\n"
  16.      . "Fibonacci( 2 ^ 'exp' ) -nek kiszamolja az utolso 'digit' szamjegyet.\n"
  17.      . "  exp   - egesz szam, 2 kitevojet jelzi (def 53) [max 97]\n"
  18.      . "  digit - egesz szam, utolso szamjegyek szamat jelzi (def 6) [max 9]\n\n";
  19. }
  20.  
  21. my $max_exp = 97;
  22. my $max_digit = 9;
  23. my $warn;
  24.  
  25. my ($exp, $digit) = @ARGV;
  26.  
  27. if (!$exp || $exp =~ /\D/) {
  28.   $warn = 1;
  29.   $exp = 53;
  30. }
  31.  
  32. if ($exp > $max_exp)
  33. {
  34.   $warn = 1;
  35.   $exp = $max_exp;
  36. }
  37.  
  38. $digit = 6 if (!$digit || $digit =~ /\D/);
  39.  
  40. if ($digit > $max_digit)
  41. {
  42.   $warn = 1;
  43.   $digit = $max_digit;
  44. }
  45.  
  46. my $mod = 10 ** $digit;
  47.  
  48. useage() if $warn;
  49.  
  50. ##### ALGORITHM by http://fusharblog.com/solving-linear-recurrence-for-programming-contest/
  51.  
  52. sub mx2_mod_mul($$)
  53. {
  54.   my ($a,$b) = @_;
  55.   return [
  56.     [($a->[0]->[0] * $b->[0]->[0]  +  $a->[0]->[1] * $b->[1]->[0]) % $mod,
  57.      ($a->[0]->[0] * $b->[0]->[1]  +  $a->[0]->[1] * $b->[1]->[1]) % $mod],
  58.     [($a->[1]->[0] * $b->[0]->[0]  +  $a->[1]->[1] * $b->[1]->[0]) % $mod,
  59.      ($a->[1]->[0] * $b->[0]->[1]  +  $a->[1]->[1] * $b->[1]->[1]) % $mod]
  60.   ];
  61. }
  62.  
  63. sub mx2_mod_pow($$);
  64. sub mx2_mod_pow($$)
  65. {
  66.   my ($a,$p) = @_;
  67.   return $a if ($p == 1);
  68.   return mx2_mod_mul($a, mx2_mod_pow($a,($p-1))) if ($p % 2);
  69.  
  70.   my $b = mx2_mod_pow($a, int($p/2));
  71.   return mx2_mod_mul ($b,$b);  
  72. }
  73.  
  74. sub get($)
  75. {
  76.   return $_[0]->[0]->[1];
  77. }
  78.  
  79. ##### RUN THE CODE
  80.  
  81. my $m = [[1,1],[1,0]];
  82. my $c = mx2_mod_pow($m, 2**$exp);
  83. print "(F.2^$exp).digit($digit) = " . get($c) . "\n";
Advertisement
Add Comment
Please, Sign In to add comment