File Coverage

blib/lib/Math/NumSeq/DigitSum.pm
Criterion Covered Total %
statement 56 57 98.2
branch 3 4 75.0
condition 1 3 33.3
subroutine 16 16 100.0
pod 3 3 100.0
total 79 83 95.1


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::DigitSum;
19 1     1   6121 use 5.004;
  1         5  
  1         70  
20 1     1   9 use strict;
  1         2  
  1         55  
21              
22 1     1   6 use vars '$VERSION', '@ISA';
  1         4  
  1         77  
23             $VERSION = 71;
24              
25 1     1   6 use Math::NumSeq;
  1         1  
  1         32  
26 1     1   7 use Math::NumSeq::Base::IterateIth;
  1         2  
  1         72  
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 Sum');
36 1     1   8 use constant description => Math::NumSeq::__('Sum of the digits in the given radix. For binary this is how many 1-bits.');
  1         2  
  1         4  
37 1     1   7 use constant values_min => 0;
  1         2  
  1         43  
38 1     1   6 use constant i_start => 0;
  1         3  
  1         51  
39 1     1   5 use constant characteristic_increasing => 0;
  1         2  
  1         147  
40 1     1   6 use constant characteristic_smaller => 1;
  1         4  
  1         52  
41 1     1   7 use constant characteristic_integer => 1;
  1         2  
  1         58  
42              
43 1     1   8 use Math::NumSeq::Base::Digits;
  1         2  
  1         107  
44 1         9 use constant parameter_info_array =>
45             [ Math::NumSeq::Base::Digits->parameter_info_list,
46             { name => 'power',
47             display => Math::NumSeq::__('Power'),
48             type => 'integer',
49             width => 1,
50             default => '1',
51             minimum => 1,
52             description => Math::NumSeq::__('Power of the digits, 1=plain sum, 2=sum of squares, 3=sum of cubes, etc.'),
53             },
54 1     1   4 ];
  1         2  
55              
56              
57             #------------------------------------------------------------------------------
58             # cf A010888 repeat DigitSum until single digit, is (n mod 9)+1, so 1 to 9
59             # A179083 even with an odd sum of digits
60             # A052018 digit sum occurs in the number
61             # A054868 sum-of-bits then sum-of-bits again
62              
63             my @oeis_anum;
64              
65             $oeis_anum[1]->[2] = 'A000120'; # 2 binary, count of 1-bits like DigitCount
66             # OEIS-Other: A000120 radix=2
67             # OEIS-Other: A000120 radix=2 power=2
68             # OEIS-Other: A000120 radix=2 power=3
69              
70             $oeis_anum[1]->[3] = 'A053735'; # 3 ternary
71             $oeis_anum[2]->[3] = 'A006287'; # 3 ternary squared digits
72             # OEIS-Catalogue: A053735 radix=3
73             # OEIS-Catalogue: A006287 radix=3 power=2
74              
75             $oeis_anum[1]->[4] = 'A053737'; # 4
76             # OEIS-Catalogue: A053737 radix=4
77              
78             $oeis_anum[1]->[5] = 'A053824'; # 5
79             # OEIS-Catalogue: A053824 radix=5
80              
81             $oeis_anum[1]->[6] = 'A053827'; # 6
82             # OEIS-Catalogue: A053827 radix=6
83              
84             $oeis_anum[1]->[7] = 'A053828'; # 7
85             # OEIS-Catalogue: A053828 radix=7
86              
87             $oeis_anum[1]->[8] = 'A053829'; # 8
88             # OEIS-Catalogue: A053829 radix=8
89              
90             $oeis_anum[1]->[9] = 'A053830'; # 9
91             # OEIS-Catalogue: A053830 radix=9
92              
93             $oeis_anum[1]->[10] = 'A007953'; # 10 decimal
94             # OEIS-Catalogue: A007953
95              
96             $oeis_anum[1]->[11] = 'A053831'; # 11
97             # OEIS-Catalogue: A053831 radix=11
98              
99             $oeis_anum[1]->[12] = 'A053832'; # 12
100             # OEIS-Catalogue: A053832 radix=12
101              
102             $oeis_anum[1]->[13] = 'A053833'; # 13
103             # OEIS-Catalogue: A053833 radix=13
104              
105             $oeis_anum[1]->[14] = 'A053834'; # 14
106             # OEIS-Catalogue: A053834 radix=14
107              
108             $oeis_anum[1]->[15] = 'A053835'; # 15
109             # OEIS-Catalogue: A053835 radix=15
110              
111             $oeis_anum[1]->[16] = 'A053836'; # 16
112             # OEIS-Catalogue: A053836 radix=16
113              
114             $oeis_anum[2]->[10] = 'A003132';
115             # OEIS-Catalogue: A003132 power=2
116              
117             $oeis_anum[3]->[10] = 'A055012';
118             # OEIS-Catalogue: A055012 power=3
119              
120             $oeis_anum[4]->[10] = 'A055013';
121             # OEIS-Catalogue: A055013 power=4
122              
123             $oeis_anum[5]->[10] = 'A055014';
124             # OEIS-Catalogue: A055014 power=5
125              
126             $oeis_anum[6]->[10] = 'A055015';
127             # OEIS-Catalogue: A055015 power=6
128              
129             sub oeis_anum {
130 3     3 1 40 my ($self) = @_;
131 3         8 my $power = $self->{'power'};
132 3         9 my $radix = $self->{'radix'};
133 3 100       12 if ($radix == 2) { $power = 1; }
  1         3  
134 3         9 return $oeis_anum[$power]->[$radix];
135             }
136              
137             #------------------------------------------------------------------------------
138              
139             # ENHANCE-ME:
140             # next() is +1 until wraps 09 to 10 is -8, or 0999 to 1000 is -998, etc
141             # radix=2 is DigitCount
142             #
143             # sub next {
144             # my ($self) = @_;
145             # my $radix = $self->{'radix'};
146             # my $sum = $self->{'sum'} + 1;
147             # if (++$self->{'digits'}->[0] >= $radix) {
148             # $self->{'digits'}->[0] = 0;
149             # my $i = 1;
150             # for (;;) {
151             # $sum++;
152             # if (++$self->{'digits'}->[$i] < $radix) {
153             # last;
154             # }
155             # }
156             # }
157             # return ($self->{'i'}++, ($self->{'sum'} = ($sum % $radix)));
158             # }
159              
160             # ENHANCE-ME: radix=2 share Math::NumSeq::DigitCount binary
161             sub ith {
162 1365     1365 1 2107 my ($self, $i) = @_;
163             ### DigitSum ith(): $i
164              
165 1365 50       3021 if (_is_infinite ($i)) {
166 0         0 return $i;
167             }
168              
169 1365         2266 my $radix = $self->{'radix'};
170 1365         1808 my $power = $self->{'power'};
171 1365         1547 my $sum = 0;
172 1365         2504 while ($i) {
173 2824         3814 $sum += ($i % $radix) ** $power;
174 2824         21935 $i = int($i/$radix);
175             }
176 1365         4539 return $sum;
177             }
178              
179             sub pred {
180 76     76 1 363 my ($self, $value) = @_;
181 76   33     285 return ($value == int($value)
182             && $value >= 0);
183             }
184              
185             1;
186             __END__