File Coverage

blib/lib/Math/NumSeq/Beastly.pm
Criterion Covered Total %
statement 66 69 95.6
branch 15 18 83.3
condition n/a
subroutine 15 15 100.0
pod 5 5 100.0
total 101 107 94.3


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::Beastly;
19 1     1   6134 use 5.004;
  1         5  
  1         51  
20 1     1   8 use strict;
  1         2  
  1         54  
21 1     1   6 use List::Util 'max';
  1         2  
  1         86  
22              
23 1     1   7 use vars '$VERSION', '@ISA';
  1         2  
  1         83  
24             $VERSION = 71;
25 1     1   7 use Math::NumSeq;
  1         3  
  1         69  
26             @ISA = ('Math::NumSeq');
27             *_is_infinite = \&Math::NumSeq::_is_infinite;
28              
29             # uncomment this to run the ### lines
30             #use Smart::Comments;
31              
32              
33             # use constant name => Math::NumSeq::__('Beastly Numbers');
34 1     1   155 use constant description => Math::NumSeq::__('Numbers which contain "666". The default is decimal, or select a radix.');
  1         3  
  1         7  
35 1     1   6 use constant i_start => 1;
  1         2  
  1         52  
36 1     1   6 use constant characteristic_increasing => 1;
  1         2  
  1         49  
37 1     1   5 use constant characteristic_integer => 1;
  1         2  
  1         85  
38              
39 1         6 use constant parameter_info_array =>
40             [
41             { name => 'radix',
42             share_key => 'radix_min_7',
43             type => 'integer',
44             display => Math::NumSeq::__('Radix'),
45             default => 10,
46             minimum => 7, # less than 7 there's no beastly values
47             width => 3,
48             description => Math::NumSeq::__('Radix, ie. base, for the values calculation. Default is decimal (base 10).'),
49             },
50 1     1   5 ];
  1         2  
51              
52             #------------------------------------------------------------------------------
53              
54             # cf A131645 the beastly primes
55             sub oeis_anum {
56 2     2 1 11 my ($self) = @_;
57 2 100       12 return ($self->{'radix'} == 10
58             ? 'A051003'
59             : undef);
60             }
61             # OEIS-Catalogue: A051003 radix=10
62              
63             #------------------------------------------------------------------------------
64              
65             sub values_min {
66 2     2 1 24 my ($self) = @_;
67 2         10 my $radix = $self->{'radix'};
68 2         10 return (6*$radix+6)*$radix+6; # at i=0
69             }
70              
71             sub rewind {
72 6     6 1 3712 my ($self) = @_;
73              
74 6         20 my $radix = $self->{'radix'};
75              
76 6         33 $self->{'i'} = $self->i_start;
77 6         21 $self->{'target'} = (6*$radix+6)*$radix+6;
78 6         16 $self->{'cube'} = $radix*$radix*$radix;
79 6         47 $self->{'value'} = $self->{'target'} - 1;
80             }
81             sub next {
82 204     204 1 3032 my ($self) = @_;
83 204 50       736 if ($self->{'radix'} < 7) {
84 0         0 return;
85             }
86 204         326 my $value = $self->{'value'};
87 204         343 for (;;) {
88 81556 100       158277 if ($self->pred(++$value)) {
89 204         1345 return ($self->{'i'}++, ($self->{'value'} = $value));
90             }
91             }
92             }
93              
94             sub pred {
95 82684     82684 1 127318 my ($self, $value) = @_;
96              
97             {
98 82684         117999 my $int = int($value);
  82684         111374  
99 82684 100       154467 if ($value != $int) {
100 512         1013 return 0;
101             }
102 82172         114031 $value = $int; # prefer BigInt if input BigFloat
103             }
104              
105 82172         122245 my $radix = $self->{'radix'};
106 82172 50       167285 if ($radix < 7) {
107 0         0 return 0; # no digit 6s at all if radix<7
108             }
109 82172 100       159412 if ($radix == 10) {
110 58060         187736 return ($value =~ /666/);
111             }
112              
113 24112 50       71182 if (_is_infinite($value)) {
114 0         0 return 0;
115             }
116              
117 24112         43963 my $cube = $self->{'cube'}; # radix^3
118 24112         33539 my $target = $self->{'target'}; # 666 in radix
119 24112         33459 for (;;) {
120 64109 100       134921 if (($value % $cube) == $target) {
121 137         351 return 1;
122             }
123 63972 100       133083 if ($value < $cube) {
124 23975         77324 return 0;
125             }
126 39997         58405 $value = int($value/$radix);
127             }
128             }
129              
130             1;
131             __END__