File Coverage

blib/lib/Math/NumSeq/DivisorCount.pm
Criterion Covered Total %
statement 54 54 100.0
branch 5 6 83.3
condition 1 3 33.3
subroutine 15 15 100.0
pod 4 4 100.0
total 79 82 96.3


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              
19             package Math::NumSeq::DivisorCount;
20 2     2   7241 use 5.004;
  2         4  
21 2     2   7 use strict;
  2         3  
  2         51  
22              
23 2     2   6 use vars '$VERSION','@ISA';
  2         2  
  2         104  
24             $VERSION = 72;
25              
26 2     2   368 use Math::NumSeq;
  2         3  
  2         40  
27 2     2   314 use Math::NumSeq::Base::IterateIth;
  2         3  
  2         52  
28             @ISA = ('Math::NumSeq::Base::IterateIth',
29             'Math::NumSeq');
30              
31 2     2   378 use Math::NumSeq::PrimeFactorCount;
  2         3  
  2         72  
32             *_prime_factors = \&Math::NumSeq::PrimeFactorCount::_prime_factors;
33              
34             # uncomment this to run the ### lines
35             #use Devel::Comments;
36              
37              
38             # use constant name => Math::NumSeq::__('Divisor Count');
39 2     2   7 use constant description => Math::NumSeq::__('Count of divisors of i (including 1 and i).');
  2         2  
  2         4  
40 2     2   6 use constant i_start => 1;
  2         7  
  2         67  
41 2     2   5 use constant characteristic_count => 1;
  2         2  
  2         60  
42 2     2   5 use constant characteristic_smaller => 1;
  2         3  
  2         66  
43 2     2   6 use constant characteristic_increasing => 0;
  2         1  
  2         489  
44              
45              
46             # "proper" divisors just means 1 less in each value, not sure much use for
47             # that.
48             #
49             # n itself -- proper, or not
50             # 1 -- proper, or not
51             # square, non-square
52             #
53             # use constant parameter_info_array =>
54             # [ { name => 'divisor_type',
55             # display => Math::NumSeq::__('Divisor Type'),
56             # type => 'enum',
57             # choices => ['all','proper'], # ,'propn1'
58             # default => 'all',
59             # # description => Math::NumSeq::__(''),
60             # },
61             # ];
62              
63              
64             my %values_min = (all => 1,
65             proper => 0,
66             propn1 => 0);
67             sub values_min {
68 1     1 1 5 my ($self) = @_;
69             # or values_min=0 if i_start=0
70 1         2 return 1; # $values_min{$self->{'divisor_type'}};
71             }
72              
73             #------------------------------------------------------------------------------
74             # cf A032741 - 1 <= d < n starting n=0
75             # A147588 - 1 < d < n starting n=1
76             #
77             # A006218 - cumulative count of divisors
78             # A002541 - cumulative proper divisors
79             #
80             # A001227 - count odd divisors
81             # A001826 - count 4k+1 divisors
82             # A038548 - count divisors <= sqrt(n)
83             # A070824 - proper divisors starting n=2
84             # A002182 - number with new highest number of divisors
85             # A002183 - that count of divisors
86             # A001876 - count 5k+1 divisors
87             # A001877 - count 5k+2 divisors
88             # A001878 - count 5k+3 divisors
89             # A001899 - count 5k+4 divisors
90             #
91             # A028422 - count of ways to factorize
92             # A033834 - n with new high count factorizations
93             # A033833 - highly factorable
94             #
95             # A056595 - count non-square divisors
96             # A046951 - count square divisors
97             # A013936 - cumulative count square divisors
98             # A137518 - same divisor count as n, and > a(n-1) so increasing
99             #
100             sub oeis_anum {
101 1     1 1 4 my ($self) = @_;
102 1         1 return 'A000005';
103             # OEIS-Catalogue: A000005
104              
105             # my %oeis_anum = (all => 'A000005', # all divisors starting n=1
106             # # proper => 'A032741', # starts n=0 ...
107             # # propn1 => 'A147588',
108             # );
109             # return $oeis_anum{$self->{'divisor_type'}};
110             }
111              
112              
113             #------------------------------------------------------------------------------
114             sub ith {
115 69     69 1 64 my ($self, $i) = @_;
116              
117 69         48 $i = abs($i);
118 69 100       87 if ($i == 0) {
119 1         3 return 0;
120             }
121              
122             # If i = p^a * q^b * ... then divisorcount = (a+1)*(b+1)*...
123             # which is each possible power p^0, p^1, ..., p^a of each prime,
124             # including all zeros p^0*q^0*... = 1 and p^a*q^b*... itself.
125             #
126             # If i is a primorial 2*3*5*7*13*... with k primes then divisorcount=2^k
127             # so the $value product can become a bignum if $i is a bignum.
128              
129 68         97 my ($good, @primes) = _prime_factors($i);
130 68 50       92 return undef unless $good;
131              
132 68         49 my $value = ($i*0) + 1; # inherit possible bignum
133 68         40 my $prev = 0;
134 68         45 my $dcount = 1;
135 68         92 while (my $p = shift @primes) {
136 86 100       94 if ($p == $prev) {
137 13         20 $dcount++;
138             } else {
139 73         37 $value *= $dcount;
140 73         51 $dcount = 2;
141 73         124 $prev = $p;
142             }
143             }
144 68         117 return $value * $dcount;
145              
146             # if ($self->{'divisor_type'} eq 'propn1') {
147             # if ($ret <= 2) {
148             # return 0;
149             # }
150             # $ret -= 2;
151             # }
152             }
153              
154             sub pred {
155 7     7 1 22 my ($self, $value) = @_;
156 7   33     41 return ($value >= 1 && $value == int($value));
157             }
158              
159             1;
160             __END__