File Coverage

blib/lib/Math/NumSeq/DigitCountLow.pm
Criterion Covered Total %
statement 59 63 93.6
branch 10 14 71.4
condition 1 3 33.3
subroutine 15 15 100.0
pod 3 3 100.0
total 88 98 89.8


line stmt bran cond sub pod time code
1             # Copyright 2010, 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::DigitCountLow;
19 1     1   1605 use 5.004;
  1         4  
20 1     1   7 use strict;
  1         2  
  1         35  
21              
22 1     1   4 use vars '$VERSION', '@ISA';
  1         1  
  1         62  
23             $VERSION = 72;
24              
25 1     1   5 use Math::NumSeq;
  1         4  
  1         19  
26 1     1   4 use Math::NumSeq::Base::IterateIth;
  1         1  
  1         65  
27             @ISA = ('Math::NumSeq::Base::IterateIth',
28             'Math::NumSeq');
29             *_is_infinite = \&Math::NumSeq::_is_infinite;
30              
31             # uncomment this to run the ### lines
32             #use Smart::Comments;
33              
34              
35             # use constant name => Math::NumSeq::__('Digit Count Low');
36 1     1   6 use constant description => Math::NumSeq::__('How many of a given digit at the low end of a number, in a given radix.');
  1         2  
  1         5  
37 1     1   6 use constant values_min => 0;
  1         2  
  1         56  
38 1     1   4 use constant default_i_start => 0;
  1         1  
  1         40  
39 1     1   3 use constant characteristic_count => 1;
  1         1  
  1         33  
40 1     1   3 use constant characteristic_smaller => 1;
  1         1  
  1         36  
41 1     1   4 use constant characteristic_increasing => 0;
  1         2  
  1         36  
42              
43 1     1   4 use Math::NumSeq::DigitCount 4; # radix,digit parameter
  1         10  
  1         304  
44             *parameter_info_array = \&Math::NumSeq::DigitCount::parameter_info_array;
45              
46             #------------------------------------------------------------------------------
47             # cf A006519 - highest k s.t. 2^k+1 divides n
48             # A001511 low 0s in 2*n, ie +1
49             # A070940 low 0s pos counting from the left
50             # A051064 low 0s of 3*n in ternary, ie +1
51             # A160094 low zeros in 10 counting from the right from 1
52             # A160093 low zeros in 10 pos counting from the left
53             #
54             my @oeis_anum;
55              
56             $oeis_anum[1]->[2]->[0] = 'A007814'; # base 2 low 0s, starting i=1
57             # OEIS-Catalogue: A007814 radix=2 digit=0 i_start=1
58              
59             $oeis_anum[1]->[3]->[0] = 'A007949'; # base 3 low 0s, starting i=1
60             # OEIS-Catalogue: A007949 radix=3 digit=0 i_start=1
61              
62             $oeis_anum[1]->[5]->[0] = 'A112765'; # base 5 low 0s, starting i=1
63             # OEIS-Catalogue: A112765 radix=5 digit=0 i_start=1
64              
65             $oeis_anum[1]->[6]->[0] = 'A122841'; # base 6 low 0s, starting i=1
66             # OEIS-Catalogue: A122841 radix=6 digit=0 i_start=1
67              
68             $oeis_anum[1]->[10]->[0] = 'A122840'; # base 10 low 0s, starting i=1
69             # OEIS-Catalogue: A122840 radix=10 digit=0 i_start=1
70              
71             sub oeis_anum {
72 4     4 1 12 my ($self) = @_;
73 4         8 my $radix = $self->{'radix'};
74 4         6 my $digit = $self->{'digit'};
75 4 50       15 if ($digit == -1) {
    50          
76 0         0 $digit = $radix-1;
77             } elsif ($digit >= $radix) {
78 0         0 return 'A000004'; # all zeros,
79             }
80 4         12 return $oeis_anum[$self->i_start]->[$radix]->[$digit];
81             }
82              
83             #------------------------------------------------------------------------------
84              
85             sub ith {
86 499     499 1 469 my ($self, $i) = @_;
87             ### DigitCountLow ith(): $i
88              
89 499         322 $i = abs($i);
90 499 50       597 if (_is_infinite($i)) {
91 0         0 return $i; # don't loop forever if $i is +infinity
92             }
93              
94 499         481 my $radix = $self->{'radix'};
95 499         332 my $digit = $self->{'digit'};
96 499 50       571 if ($digit == -1) { $digit = $radix - 1; }
  0         0  
97              
98 499         303 my $count = 0;
99 499 100       468 if ($radix == 2) {
100             ### binary ...
101 172         202 while ($i) {
102 289 100       343 last unless (($i & 1) == $digit);
103 158         104 $count++;
104 158         168 $i >>= 1;
105             }
106             } else {
107             ### general radix: $radix
108 327         379 while ($i) {
109 417 100       540 last unless (($i % $radix) == $digit);
110 104         98 $count++;
111 104         146 $i = int($i/$radix);
112             }
113             }
114 499         774 return $count;
115             }
116              
117             sub pred {
118 43     43 1 123 my ($self, $value) = @_;
119 43   33     110 return ($value >= 0 && $value == int($value));
120             }
121              
122             1;
123             __END__