File Coverage

blib/lib/Math/NumSeq/MoranNumbers.pm
Criterion Covered Total %
statement 54 56 96.4
branch 10 12 83.3
condition 2 3 66.6
subroutine 13 13 100.0
pod 3 3 100.0
total 82 87 94.2


line stmt bran cond sub pod time code
1             # Copyright 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::MoranNumbers;
19 1     1   93705 use 5.004;
  1         4  
  1         53  
20 1     1   8 use strict;
  1         3  
  1         60  
21 1     1   6 use Math::Prime::XS 0.23 'is_prime'; # version 0.23 fix for 1928099
  1         21  
  1         64  
22              
23 1     1   7 use vars '$VERSION', '@ISA';
  1         13  
  1         82  
24             $VERSION = 71;
25              
26 1     1   6 use Math::NumSeq;
  1         3  
  1         21  
27 1     1   13 use Math::NumSeq::Base::IteratePred;
  1         2  
  1         74  
28             @ISA = ('Math::NumSeq::Base::IteratePred',
29             'Math::NumSeq');
30             *_is_infinite = \&Math::NumSeq::_is_infinite;
31              
32             # uncomment this to run the ### lines
33             #use Devel::Comments;
34              
35 1     1   8 use constant name => Math::NumSeq::__('Moran Numbers');
  1         3  
  1         6  
36 1     1   6 use constant description => Math::NumSeq::__('Moran numbers, divisible by the sum of their digits and that division resulting in a prime.');
  1         3  
  1         4  
37 1     1   6 use constant i_start => 1;
  1         2  
  1         57  
38              
39             use Math::NumSeq::Base::Digits
40 1     1   6 'parameter_info_array'; # radix parameter
  1         2  
  1         384  
41              
42             sub values_min {
43 4     4 1 21 my ($self) = @_;
44 4 100       18 if (! $self->{'values_min'}) {
45 1         4 for (my $value = $self->{'radix'}; ; $value++) {
46 9 100       21 if ($self->pred($value)) {
47 1         7 $self->{'values_min'} = $value;
48 1         3 last;
49             }
50             }
51             }
52 4         16 return $self->{'values_min'};
53             }
54              
55             #------------------------------------------------------------------------------
56             # cf A007953 digit sum (in Math::NumSeq::DigitSum)
57             # A085775 both n/digitsum(n) and (n+1)/digitsum(n+1) prime
58             # A108780 n/digitsum(n) is a golden semiprime
59             # A130338 primes not occurring as n/digitsum(n)
60             # A003635 inconsummate, quotients not occuring as n/digitsum(n)
61             #
62             my @oeis_anum;
63             $oeis_anum[10] = 'A001101'; # OFFSET=1
64             # OEIS-Catalogue: A001101
65              
66             sub oeis_anum {
67 1     1 1 5 my ($self) = @_;
68 1         3 return $oeis_anum[$self->{'radix'}];
69             }
70              
71             #------------------------------------------------------------------------------
72              
73             sub pred {
74 578     578 1 2577 my ($self, $value) = @_;
75             ### MoranNumbers pred(): $value
76              
77 578 100 66     4430 if ($value <= 0 || $value != int($value)) {
78 138         658 return 0;
79             }
80 440 50       1274 if (_is_infinite($value)) {
81 0         0 return undef;
82             }
83              
84 440         1016 my $radix = $self->{'radix'};
85 440         755 my $sum = 0;
86 440         717 my $v = $value;
87 440         1385 while ($v) {
88 1058         1622 $sum += ($v % $radix);
89 1058         3333 $v = int($v/$radix);
90             }
91 440 100       1336 if ($value % $sum) {
92 303         7929 return 0;
93             }
94 137         270 $value /= $sum;
95 137 50       454 if ($value > 0xFFFF_FFFF) {
96 0         0 return undef;
97             }
98 137         736 return is_prime($value);
99             }
100              
101             1;
102             __END__