File Coverage

blib/lib/Math/NumSeq/OEIS/Catalogue/Plugin/FractionDigits.pm
Criterion Covered Total %
statement 49 57 85.9
branch 8 14 57.1
condition 5 18 27.7
subroutine 14 15 93.3
pod 0 6 0.0
total 76 110 69.0


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::OEIS::Catalogue::Plugin::FractionDigits;
19 3     3   11869 use 5.004;
  3         10  
  3         125  
20 3     3   16 use strict;
  3         5  
  3         142  
21 3     3   17 use List::Util 'min', 'max'; # FIXME: 5.6 only, maybe
  3         4  
  3         328  
22              
23 3     3   14 use vars '@ISA';
  3         5  
  3         121  
24 3     3   566 use Math::NumSeq::OEIS::Catalogue::Plugin;
  3         5  
  3         111  
25             @ISA = ('Math::NumSeq::OEIS::Catalogue::Plugin');
26              
27 3     3   26 use vars '$VERSION';
  3         13  
  3         128  
28             $VERSION = 71;
29              
30             # uncomment this to run the ### lines
31             #use Smart::Comments;
32              
33              
34 3     3   58 use constant num_first => 21022; # A021022 1/18
  3         6  
  3         172  
35 3     3   12 use constant num_last => 21999; # A021999 1/995
  3         5  
  3         1851  
36              
37             my %exclude = (21029 => 1, # A021029 is not 1/25 (0.0400000...)
38             21048 => 1, # A021048 is not 1/44 (0.0227272...)
39             21049 => 1, # A021049 is not 1/45 (0.0222222...)
40             21076 => 1, # A021076 is not 1/72 (0.0138888...)
41             21079 => 1, # A021079 is not 1/75 (0.0133333...)
42             21092 => 1, # A021092 is not 1/88 (0.011363636...)
43             21103 => 1, # A021103 is not 1/99 (0.0101010101...)
44             21129 => 1, # A021129 is not 1/125
45             21229 => 1, # A021229 is not 1/225
46             21268 => 1, # A021268 is not 1/264
47             21279 => 1, # A021279 is not 1/275
48             21379 => 1, # A021379 is not 1/375
49             21629 => 1, # A021629 is not 1/625
50             21829 => 1, # A021829 is not 1/825
51             );
52             sub anum_after {
53 66     66 0 3297 my ($class, $anum) = @_;
54             ### anum_after(): $anum
55              
56 66         249 my $num = _anum_to_num($anum) + 1;
57             ### $num
58 66 100 66     358 if (($class->num_to_denominator($num) % 10) == 0
59             || $exclude{$num}) {
60             ### skip ...
61 1         2 $num++;
62             }
63 66 50       374 if ($num > $class->num_last) {
64 0         0 return undef;
65             }
66             ### ret: $num
67 66         1101 return sprintf 'A%06d', max ($num, $class->num_first);
68             }
69              
70             sub anum_before {
71 66     66 0 220 my ($class, $anum) = @_;
72             ### anum_before(): $anum
73              
74 66         234 my $num = _anum_to_num($anum) - 1;
75 66 100 66     372 if (($class->num_to_denominator($num) % 10) == 0
76             || $exclude{$num}) {
77             ### skip ...
78 1         3 $num--;
79             }
80 66 50       626 if ($num <= $class->num_first) {
81 0         0 return undef;
82             }
83             ### ret: $num
84 66         1073 return sprintf 'A%06d', min ($num, $class->num_last);
85             }
86              
87             sub _anum_to_num {
88 132     132   317 my ($anum) = @_;
89 132 50 33     2261 if ($anum =~ /A0*([0-9]+)/ || $anum =~ /([1-9][0-9]*)/) {
90 132         1502 return $1;
91             } else {
92 0         0 return 0;
93             }
94             }
95              
96             sub anum_to_info {
97 0     0 0 0 my ($class, $anum) = @_;
98             ### FractionDigits anum_to_info(): $anum
99              
100             # Math::NumSeq::FractionDigits
101             # fraction=1/k radix=10 for k=11 to 995 is anum=21004+k,
102             # being A021015 through A021999, though 1/11 is also A010680 and prefer
103             # that one (in BuiltinTable.pm)
104              
105 0         0 my $num = _anum_to_num($anum);
106             ### $num
107 0 0 0     0 if (($class->num_to_denominator($num) % 10) != 0
      0        
      0        
108             && ! $exclude{$num}
109             && $num >= $class->num_first
110             && $num <= $class->num_last) {
111 0         0 return $class->make_info($num);
112             } else {
113 0         0 return undef;
114             }
115             }
116              
117             my @info_array;
118             sub info_arrayref {
119 1     1 0 2 my ($class) = @_;
120 1 50       6 if (! @info_array) {
121 881         2625 @info_array = map {$class->make_info($_)}
  978         2256  
122 1         44 grep {($_ % 10) != 0}
123             $class->num_first .. $class->num_last;
124             ### made info_arrayref: @info_array
125             }
126 1         56 return \@info_array;
127             }
128              
129             sub make_info {
130 881     881 0 1850 my ($class, $num) = @_;
131             ### make_info(): $num
132 881         2732 return { anum => sprintf('A%06d', $num),
133             class => 'Math::NumSeq::FractionDigits',
134             parameters =>
135             [ fraction => '1/'.$class->num_to_denominator($num),
136             radix => 10,
137             ],
138             };
139             }
140              
141             sub num_to_denominator {
142 1013     1013 0 1855 my ($class, $num) = @_;
143 1013         10043 return ($num-21004);
144             }
145              
146             1;
147             __END__