line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#!/usr/bin/perl |
2
|
|
|
|
|
|
|
# |
3
|
|
|
|
|
|
|
# Computes the Fibonacci sequence using the fast algorithm: F(n) ~ g^n/sqrt(5), |
4
|
|
|
|
|
|
|
# where g is the golden ratio and ~ stands for "take the nearest integer." |
5
|
|
|
|
|
|
|
# |
6
|
|
|
|
|
|
|
# Copyright (c) 1999-2000, Vipul Ved Prakash |
7
|
|
|
|
|
|
|
# This code is free software distributed under the same license as Perl itself. |
8
|
|
|
|
|
|
|
# $Id: Fibonacci.pm,v 1.5 2001/04/28 20:41:15 vipul Exp $ |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
package Math::Fibonacci; |
11
|
2
|
|
|
2
|
|
16873
|
use strict; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
65
|
|
12
|
2
|
|
|
2
|
|
11
|
use vars qw($VERSION @ISA @EXPORT_OK); |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
113
|
|
13
|
2
|
|
|
2
|
|
2154
|
use POSIX qw(log10 ceil floor); |
|
2
|
|
|
|
|
16971
|
|
|
2
|
|
|
|
|
17
|
|
14
|
|
|
|
|
|
|
require Exporter; |
15
|
|
|
|
|
|
|
@ISA = qw(Exporter); |
16
|
|
|
|
|
|
|
( $VERSION ) = '$Revision: 1.5 $' =~ /\s(\d+\.\d+)\s/; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
@EXPORT_OK = qw(term series decompose isfibonacci); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
sub g () { "1.61803398874989" } # golden ratio |
21
|
|
|
|
|
|
|
|
22
|
51
|
|
|
51
|
1
|
172
|
sub term { nearestint ((g ** shift) / sqrt(5)) } # nth term of the seq |
23
|
|
|
|
|
|
|
|
24
|
1
|
|
|
1
|
1
|
9
|
sub series { return map(term($_), 1..shift) } # n terms of the seq |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
sub decompose { # decomposes any integer into the sum of |
28
|
|
|
|
|
|
|
# members of the fibonacci sequence. |
29
|
1
|
|
|
1
|
1
|
10
|
my ($int) = @_; |
30
|
1
|
|
|
|
|
5
|
my $sum = decomp ($int); |
31
|
1
|
|
|
|
|
6
|
return @$sum; |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
} |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
sub decomp { |
36
|
9
|
|
|
9
|
0
|
10
|
my ($a, $sum) = @_; |
37
|
9
|
|
|
|
|
61
|
my $n = nearestint ((log10($a) + log10(sqrt(5)))/log10(g)); |
38
|
9
|
|
|
|
|
16
|
my $fibn = term($n); |
39
|
9
|
100
|
|
|
|
29
|
if ( $fibn == $a ) { push @$sum, $a; return $sum } |
|
1
|
100
|
|
|
|
3
|
|
|
1
|
50
|
|
|
|
8
|
|
40
|
4
|
|
|
|
|
5
|
elsif ( $fibn < $a ) { push @$sum, $fibn; decomp( $a-$fibn, $sum ) } |
|
4
|
|
|
|
|
24
|
|
41
|
4
|
|
|
|
|
8
|
elsif ( $a < $fibn ) { my $fibn1 = term($n-1); push @$sum, $fibn1; |
|
4
|
|
|
|
|
5
|
|
42
|
4
|
|
|
|
|
19
|
decomp( $a - $fibn1, $sum ) } |
43
|
|
|
|
|
|
|
}; |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
sub isfibonacci { |
47
|
|
|
|
|
|
|
|
48
|
14
|
|
|
14
|
1
|
1616
|
my $a = shift; |
49
|
14
|
|
|
|
|
114
|
my $n = nearestint ((log10($a) + log10(sqrt(5)))/log10(g)); |
50
|
14
|
100
|
|
|
|
30
|
return $a == term($n) ? $n : 0; |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub nearestint { |
55
|
74
|
|
|
74
|
0
|
81
|
my $v = shift; |
56
|
74
|
|
|
|
|
119
|
my $f = floor($v); my $c = ceil($v); |
|
74
|
|
|
|
|
113
|
|
57
|
74
|
100
|
|
|
|
284
|
($v-$f) < ($c-$v) ? $f : $c; |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
# routines to implement term and series with the familiar additive algorithm. |
62
|
|
|
|
|
|
|
|
63
|
0
|
0
|
|
0
|
0
|
|
sub a_term { return $_[0] < 3 ? 1 : a_term($_[0]-1) + a_term ($_[0]-2) } |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub a_series { |
66
|
0
|
|
|
0
|
0
|
|
my @series = map(a_term($_), 1..shift); |
67
|
0
|
|
|
|
|
|
\@series; |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
1; |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=head1 NAME |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
Math::Fibonacci - Fibonacci numbers. |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=head1 VERSION |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
$Revision: 1.5 $ |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=head1 SYNOPSIS |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
use Math::Fibonacci qw(term series decompose); |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
my $term = term ( 42 ); |
87
|
|
|
|
|
|
|
my @series = series ( 42 ); |
88
|
|
|
|
|
|
|
my @sum = decompose ( 65535 ); |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
=head1 DESCRIPTION |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
This module provides a few functions related to Fibonacci numbers. |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=head1 EXPORTS ON REQUEST |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
term(), series() decompose(), isfibonacci() |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=head1 FUNCTIONS |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=over 4 |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=item B |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
Returns the $n-th term of the Fibonacci sequence. The term is computed |
105
|
|
|
|
|
|
|
using the fast algorithm: C, where g is the golden |
106
|
|
|
|
|
|
|
ratio and ~ means "take the nearest integer". |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=item B |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
Computes and returns the first $n Fibonacci numbers. |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=item B |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
Decomposes $int into the sum of Fibonacci numbers. Returns the list of |
115
|
|
|
|
|
|
|
Fibonacci numbers. |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
=item B |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
Returns the sequence number of $int if it is a Fibonacci number or a |
120
|
|
|
|
|
|
|
non-true value if it is not. |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=head1 AUTHOR |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
Vipul Ved Prakash, Email@vipul.netE |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
=head1 LICENSE |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
Copyright (c) 1999-2001, Vipul Ved Prakash. |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
This code is free software; you can redistribute it and/or modify it under |
131
|
|
|
|
|
|
|
the ARTISTIC license (a copy is included in the distribution) or under the |
132
|
|
|
|
|
|
|
same terms as Perl itself. |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
=cut |
135
|
|
|
|
|
|
|
|