File Coverage

blib/lib/Math/NumSeq/DigitCountLow.pm
Criterion Covered Total %
statement 60 64 93.7
branch 10 14 71.4
condition 1 3 33.3
subroutine 15 15 100.0
pod 3 3 100.0
total 89 99 89.9


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   8929 use 5.004;
  1         5  
  1         62  
20 1     1   9 use strict;
  1         2  
  1         56  
21              
22 1     1   8 use vars '$VERSION', '@ISA';
  1         4  
  1         102  
23             $VERSION = 71;
24              
25 1     1   5 use Math::NumSeq;
  1         4  
  1         20  
26 1     1   6 use Math::NumSeq::Base::IterateIth;
  1         5  
  1         78  
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         6  
37 1     1   6 use constant values_min => 0;
  1         2  
  1         51  
38 1     1   5 use constant default_i_start => 0;
  1         3  
  1         45  
39 1     1   6 use constant characteristic_count => 1;
  1         2  
  1         66  
40 1     1   5 use constant characteristic_smaller => 1;
  1         2  
  1         40  
41 1     1   6 use constant characteristic_increasing => 0;
  1         2  
  1         64  
42              
43 1     1   7 use Math::NumSeq::DigitCount 4; # radix,digit parameter
  1         19  
  1         540  
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 20 my ($self) = @_;
73 4         9 my $radix = $self->{'radix'};
74 4         7 my $digit = $self->{'digit'};
75 4 50       20 if ($digit == -1) {
    50          
76 0         0 $digit = $radix-1;
77             } elsif ($digit >= $radix) {
78 0         0 return 'A000004'; # all zeros,
79             }
80 4         13 return $oeis_anum[$self->i_start]->[$radix]->[$digit];
81             }
82              
83             #------------------------------------------------------------------------------
84              
85             sub ith {
86 499     499 1 835 my ($self, $i) = @_;
87             ### DigitCountLow ith(): $i
88              
89 499         566 $i = abs($i);
90 499 50       965 if (_is_infinite($i)) {
91 0         0 return $i; # don't loop forever if $i is +infinity
92             }
93              
94 499         817 my $radix = $self->{'radix'};
95 499         624 my $digit = $self->{'digit'};
96 499 50       898 if ($digit == -1) { $digit = $radix - 1; }
  0         0  
97              
98 499         554 my $count = 0;
99 499 100       784 if ($radix == 2) {
100             ### binary ...
101 172         299 while ($i) {
102 289 100       689 last unless (($i & 1) == $digit);
103 158         168 $count++;
104 158         259 $i >>= 1;
105             }
106             } else {
107             ### general radix: $radix
108 327         552 while ($i) {
109 417 100       841 last unless (($i % $radix) == $digit);
110 104         106 $count++;
111 104         204 $i = int($i/$radix);
112             }
113             }
114 499         1372 return $count;
115             }
116              
117             sub pred {
118 43     43 1 188 my ($self, $value) = @_;
119 43   33     158 return ($value >= 0 && $value == int($value));
120             }
121              
122             1;
123             __END__