line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Math::GrahamFunction::SqFacts; |
2
|
|
|
|
|
|
|
$Math::GrahamFunction::SqFacts::VERSION = '0.02003'; |
3
|
2
|
|
|
2
|
|
14
|
use strict; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
61
|
|
4
|
2
|
|
|
2
|
|
12
|
use warnings; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
56
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
|
7
|
2
|
|
|
2
|
|
9
|
use parent qw(Math::GrahamFunction::Object); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
21
|
|
8
|
|
|
|
|
|
|
|
9
|
2
|
|
|
2
|
|
124
|
use List::Util (); |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
1471
|
|
10
|
|
|
|
|
|
|
__PACKAGE__->mk_accessors(qw(n factors)); |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
sub _initialize |
13
|
|
|
|
|
|
|
{ |
14
|
1771
|
|
|
1771
|
|
2546
|
my $self = shift; |
15
|
1771
|
|
|
|
|
2601
|
my $args = shift; |
16
|
|
|
|
|
|
|
|
17
|
1771
|
100
|
|
|
|
3709
|
if ( $args->{n} ) |
|
|
50
|
|
|
|
|
|
18
|
|
|
|
|
|
|
{ |
19
|
844
|
|
|
|
|
2230
|
$self->n( $args->{n} ); |
20
|
|
|
|
|
|
|
|
21
|
844
|
|
|
|
|
8497
|
$self->_calc_sq_factors(); |
22
|
|
|
|
|
|
|
} |
23
|
|
|
|
|
|
|
elsif ( $args->{factors} ) |
24
|
|
|
|
|
|
|
{ |
25
|
927
|
|
|
|
|
1870
|
$self->factors( $args->{factors} ); |
26
|
|
|
|
|
|
|
} |
27
|
|
|
|
|
|
|
else |
28
|
|
|
|
|
|
|
{ |
29
|
0
|
|
|
|
|
0
|
die "factors or n must be supplied."; |
30
|
|
|
|
|
|
|
} |
31
|
|
|
|
|
|
|
|
32
|
1771
|
|
|
|
|
10623
|
return 0; |
33
|
|
|
|
|
|
|
} |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
sub clone |
37
|
|
|
|
|
|
|
{ |
38
|
182
|
|
|
182
|
1
|
995
|
my $self = shift; |
39
|
182
|
|
|
|
|
270
|
return __PACKAGE__->new( { 'factors' => [ @{ $self->factors() } ] } ); |
|
182
|
|
|
|
|
357
|
|
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
sub _calc_sq_factors |
43
|
|
|
|
|
|
|
{ |
44
|
844
|
|
|
844
|
|
1302
|
my $self = shift; |
45
|
|
|
|
|
|
|
|
46
|
844
|
|
|
|
|
1656
|
$self->factors( $self->_get_sq_facts( $self->n() ) ); |
47
|
|
|
|
|
|
|
|
48
|
844
|
|
|
|
|
8070
|
return 0; |
49
|
|
|
|
|
|
|
} |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
my %gsf_cache = ( 1 => [] ); |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
sub _get_sq_facts |
54
|
|
|
|
|
|
|
{ |
55
|
973
|
|
|
973
|
|
7920
|
my $self = shift; |
56
|
973
|
|
|
|
|
1401
|
my $n = shift; |
57
|
|
|
|
|
|
|
|
58
|
973
|
100
|
|
|
|
2665
|
if ( exists( $gsf_cache{$n} ) ) |
59
|
|
|
|
|
|
|
{ |
60
|
844
|
|
|
|
|
2524
|
return $gsf_cache{$n}; |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
129
|
|
100
|
|
|
424
|
my $start_from = shift || 2; |
64
|
|
|
|
|
|
|
|
65
|
129
|
|
|
|
|
218
|
for ( my $p = $start_from ; ; ++$p ) |
66
|
|
|
|
|
|
|
{ |
67
|
1720
|
100
|
|
|
|
2997
|
if ( $n % $p == 0 ) |
68
|
|
|
|
|
|
|
{ |
69
|
|
|
|
|
|
|
# This function is recursive to make better use of the Memoization |
70
|
|
|
|
|
|
|
# feature. |
71
|
129
|
|
|
|
|
354
|
my $division_factors = $self->_get_sq_facts( ( $n / $p ), $p ); |
72
|
129
|
100
|
100
|
|
|
477
|
if ( @$division_factors && ( $division_factors->[0] == $p ) ) |
73
|
|
|
|
|
|
|
{ |
74
|
|
|
|
|
|
|
return ( $gsf_cache{$n} = |
75
|
29
|
|
|
|
|
92
|
[ @{$division_factors}[ 1 .. $#$division_factors ] ] ); |
|
29
|
|
|
|
|
170
|
|
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
else |
78
|
|
|
|
|
|
|
{ |
79
|
100
|
|
|
|
|
555
|
return ( $gsf_cache{$n} = [ $p, @$division_factors ] ); |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
# Removed because it is too slow - we now use our own custom memoization ( |
86
|
|
|
|
|
|
|
# or perhaps it is just called caching) |
87
|
|
|
|
|
|
|
# memoize('get_squaring_factors', 'NORMALIZER' => sub { return $_[0]; }); |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
# This function multiplies the squaring factors of $n and $m to receive |
90
|
|
|
|
|
|
|
# the squaring factors of ($n*$m) |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
# OOP-Wise, it should be a multi-method, but since we don't inherit this |
93
|
|
|
|
|
|
|
# object it's all-right. |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
sub mult_by |
97
|
|
|
|
|
|
|
{ |
98
|
2042
|
|
|
2042
|
1
|
30959
|
my $n_ref = shift; |
99
|
2042
|
|
|
|
|
2890
|
my $m_ref = shift; |
100
|
|
|
|
|
|
|
|
101
|
2042
|
|
|
|
|
2788
|
my @n = @{ $n_ref->factors() }; |
|
2042
|
|
|
|
|
3618
|
|
102
|
2042
|
|
|
|
|
18930
|
my @m = eval { @{ $m_ref->factors() }; }; |
|
2042
|
|
|
|
|
2787
|
|
|
2042
|
|
|
|
|
3827
|
|
103
|
2042
|
50
|
|
|
|
20178
|
if ($@) |
104
|
|
|
|
|
|
|
{ |
105
|
0
|
|
|
|
|
0
|
print "Hello\n"; |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
2042
|
|
|
|
|
2881
|
my @ret = (); |
109
|
|
|
|
|
|
|
|
110
|
2042
|
|
100
|
|
|
6546
|
while ( scalar(@n) && scalar(@m) ) |
111
|
|
|
|
|
|
|
{ |
112
|
4255
|
100
|
|
|
|
8754
|
if ( $n[0] == $m[0] ) |
|
|
100
|
|
|
|
|
|
113
|
|
|
|
|
|
|
{ |
114
|
1836
|
|
|
|
|
2590
|
shift(@n); |
115
|
1836
|
|
|
|
|
4358
|
shift(@m); |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
elsif ( $n[0] < $m[0] ) |
118
|
|
|
|
|
|
|
{ |
119
|
1315
|
|
|
|
|
4162
|
push @ret, shift(@n); |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
else |
122
|
|
|
|
|
|
|
{ |
123
|
1104
|
|
|
|
|
3691
|
push @ret, shift(@m); |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
} |
126
|
2042
|
|
|
|
|
3663
|
push @ret, @n, @m; |
127
|
|
|
|
|
|
|
|
128
|
2042
|
|
|
|
|
5493
|
$n_ref->factors( \@ret ); |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# 0 for success |
131
|
2042
|
|
|
|
|
21766
|
return 0; |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
sub mult |
136
|
|
|
|
|
|
|
{ |
137
|
90
|
|
|
90
|
1
|
1471
|
my $n = shift; |
138
|
90
|
|
|
|
|
134
|
my $m = shift; |
139
|
|
|
|
|
|
|
|
140
|
90
|
|
|
|
|
190
|
my $result = $n->clone(); |
141
|
90
|
|
|
|
|
247
|
$result->mult_by($m); |
142
|
90
|
|
|
|
|
185
|
return $result; |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
sub is_square |
147
|
|
|
|
|
|
|
{ |
148
|
1364
|
|
|
1364
|
1
|
12111
|
my $self = shift; |
149
|
1364
|
|
|
|
|
2012
|
return ( scalar( @{ $self->factors() } ) == 0 ); |
|
1364
|
|
|
|
|
2447
|
|
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
sub exists |
154
|
|
|
|
|
|
|
{ |
155
|
1949
|
|
|
1949
|
1
|
17236
|
my ( $self, $factor ) = @_; |
156
|
|
|
|
|
|
|
|
157
|
1949
|
|
|
2940
|
|
5505
|
return defined( List::Util::first { $_ == $factor } @{ $self->factors() } ); |
|
2940
|
|
|
|
|
25645
|
|
|
1949
|
|
|
|
|
3804
|
|
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
sub last |
162
|
|
|
|
|
|
|
{ |
163
|
90
|
|
|
90
|
1
|
810
|
my $self = shift; |
164
|
|
|
|
|
|
|
|
165
|
90
|
|
|
|
|
193
|
return $self->factors()->[-1]; |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
|
168
|
2
|
|
|
2
|
|
16
|
use vars qw($a $b); |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
312
|
|
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
sub product |
172
|
|
|
|
|
|
|
{ |
173
|
90
|
|
|
90
|
1
|
136
|
my $self = shift; |
174
|
|
|
|
|
|
|
|
175
|
90
|
|
|
43
|
|
273
|
return ( List::Util::reduce { $a * $b } @{ $self->factors() } ); |
|
43
|
|
|
|
|
454
|
|
|
90
|
|
|
|
|
194
|
|
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
sub first |
180
|
|
|
|
|
|
|
{ |
181
|
600
|
|
|
600
|
1
|
5343
|
my $self = shift; |
182
|
|
|
|
|
|
|
|
183
|
600
|
|
|
|
|
1111
|
return $self->factors()->[0]; |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
1; |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
__END__ |