File Coverage

blib/lib/Math/NumSeq/PowerPart.pm
Criterion Covered Total %
statement 63 65 96.9
branch 10 14 71.4
condition 4 6 66.6
subroutine 17 17 100.0
pod 4 4 100.0
total 98 106 92.4


line stmt bran cond sub pod time code
1             # Copyright 2011, 2012, 2013, 2014 Kevin Ryde
2              
3             # This file is part of Math-NumSeq.
4             #
5             # Math-NumSeq is free software; you can redistribute it and/or modify
6             # it under the terms of the GNU General Public License as published by the
7             # Free Software Foundation; either version 3, or (at your option) any later
8             # version.
9             #
10             # Math-NumSeq is distributed in the hope that it will be useful, but
11             # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12             # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13             # for more details.
14             #
15             # You should have received a copy of the GNU General Public License along
16             # with Math-NumSeq. If not, see .
17              
18             package Math::NumSeq::PowerPart;
19 1     1   2179 use 5.004;
  1         4  
  1         45  
20 1     1   7 use strict;
  1         4  
  1         45  
21              
22 1     1   6 use vars '$VERSION','@ISA';
  1         1  
  1         81  
23             $VERSION = 71;
24              
25 1     1   6 use Math::NumSeq;
  1         2  
  1         25  
26 1     1   7 use Math::NumSeq::Base::IterateIth;
  1         2  
  1         55  
27             @ISA = ('Math::NumSeq::Base::IterateIth',
28             'Math::NumSeq');
29             *_is_infinite = \&Math::NumSeq::_is_infinite;
30              
31 1     1   7 use Math::NumSeq::PrimeFactorCount;
  1         2  
  1         49  
32             *_prime_factors = \&Math::NumSeq::PrimeFactorCount::_prime_factors;
33              
34             # uncomment this to run the ### lines
35             #use Smart::Comments;
36              
37              
38             # use constant name => Math::NumSeq::__('Powered Part');
39 1     1   6 use constant characteristic_non_decreasing => 0;
  1         2  
  1         64  
40 1     1   6 use constant characteristic_increasing => 0;
  1         2  
  1         44  
41 1     1   6 use constant characteristic_integer => 1;
  1         8  
  1         40  
42 1     1   5 use constant characteristic_smaller => 1;
  1         2  
  1         58  
43 1     1   4 use constant values_min => 1;
  1         2  
  1         38  
44 1     1   5 use constant i_start => 1;
  1         2  
  1         163  
45              
46             sub description {
47 4     4 1 15 my ($self) = @_;
48 4 50 100     13 return sprintf(Math::NumSeq::__('Largest %s dividing i.'),
    100          
49             ! ref $self || $self->{'power'} == 2 ? 'square'
50             : $self->{'power'} == 3 ? 'cube'
51             : sprintf('%sth',$self->{'power'}));
52             }
53              
54 1         367 use constant parameter_info_array =>
55             [
56             { name => 'power',
57             type => 'integer',
58             default => '2',
59             minimum => 2,
60             width => 2,
61             # description => Math::NumSeq::__(''),
62             },
63 1     1   5 ];
  1         3  
64              
65             #------------------------------------------------------------------------------
66             # cf A008833 - largest square dividing n
67             # A008834 - largest cube dividing n
68             # A008835 - largest 4th power dividing n
69             #
70             my @oeis_anum
71             = (
72             # OEIS-Catalogue array begin
73             undef,
74             undef,
75             'A000188', # # 2 sqrt of largest square dividing n
76             'A053150', # power=3 # 3 cbrt of largest cube dividing n
77             'A053164', # power=4 # 4th root of largest 4th power dividing n
78             # OEIS-Catalogue array end
79             );
80             sub oeis_anum {
81 2     2 1 9 my ($self) = @_;
82 2         7 return $oeis_anum[$self->{'power'}];
83             }
84              
85             #------------------------------------------------------------------------------
86              
87             sub ith {
88 392     392 1 870 my ($self, $i) = @_;
89             ### PowerPart ith(): $i
90              
91 392         513 $i = abs($i);
92 392         730 my $power = $self->{'power'};
93 392 50       965 if ($power < 2) {
94 0         0 return $i;
95             }
96 392 50       979 unless ($i >= 0) {
97 0         0 return undef;
98             }
99 392         1121 my ($good, @primes) = _prime_factors($i);
100 392 50       990 return undef unless $good;
101              
102 392         613 my $prev = 0;
103 392         473 my $count = 0;
104 392         941 my $ret = 1;
105 392         899 foreach my $p (@primes) {
106             ### $p
107 737 100       1330 if ($p == $prev) {
108             ### same ...
109             ### $count
110 217 100       829 if (++$count == $power) {
111             ### incorporate ...
112 59         70 $ret *= $p;
113 59         104 $count = 0;
114             }
115             } else {
116             ### different ...
117 520         943 $count = 1;
118 520         1101 $prev = $p;
119             }
120             }
121 392         2171 return $ret;
122             }
123              
124             sub pred {
125 28     28 1 151 my ($self, $value) = @_;
126 28   33     133 return ($value == int($value) && $value >= 1);
127             }
128              
129             1;
130             __END__