File Coverage

blib/lib/Math/NumSeq/Beastly.pm
Criterion Covered Total %
statement 65 68 95.5
branch 15 18 83.3
condition n/a
subroutine 15 15 100.0
pod 5 5 100.0
total 100 106 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   1229 use 5.004;
  1         3  
20 1     1   4 use strict;
  1         2  
  1         22  
21 1     1   4 use List::Util 'max';
  1         1  
  1         57  
22              
23 1     1   3 use vars '$VERSION', '@ISA';
  1         1  
  1         54  
24             $VERSION = 72;
25 1     1   4 use Math::NumSeq;
  1         1  
  1         61  
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   6 use constant description => Math::NumSeq::__('Numbers which contain "666". The default is decimal, or select a radix.');
  1         2  
  1         4  
35 1     1   3 use constant i_start => 1;
  1         2  
  1         33  
36 1     1   4 use constant characteristic_increasing => 1;
  1         0  
  1         37  
37 1     1   3 use constant characteristic_integer => 1;
  1         5  
  1         62  
38              
39 1         2 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   4 ];
  1         1  
51              
52             #------------------------------------------------------------------------------
53              
54             # cf A131645 the beastly primes
55             sub oeis_anum {
56 2     2 1 6 my ($self) = @_;
57 2 100       7 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 14 my ($self) = @_;
67 2         5 my $radix = $self->{'radix'};
68 2         7 return (6*$radix+6)*$radix+6; # at i=0
69             }
70              
71             sub rewind {
72 6     6 1 2195 my ($self) = @_;
73              
74 6         11 my $radix = $self->{'radix'};
75              
76 6         21 $self->{'i'} = $self->i_start;
77 6         15 $self->{'target'} = (6*$radix+6)*$radix+6;
78 6         13 $self->{'cube'} = $radix*$radix*$radix;
79 6         27 $self->{'value'} = $self->{'target'} - 1;
80             }
81             sub next {
82 204     204 1 1220 my ($self) = @_;
83 204 50       290 if ($self->{'radix'} < 7) {
84 0         0 return;
85             }
86 204         153 my $value = $self->{'value'};
87 204         130 for (;;) {
88 81556 100       79727 if ($self->pred(++$value)) {
89 204         462 return ($self->{'i'}++, ($self->{'value'} = $value));
90             }
91             }
92             }
93              
94             sub pred {
95 82684     82684 1 58578 my ($self, $value) = @_;
96              
97             {
98 82684         45704 my $int = int($value);
  82684         48021  
99 82684 100       92316 if ($value != $int) {
100 512         436 return 0;
101             }
102 82172         52104 $value = $int; # prefer BigInt if input BigFloat
103             }
104              
105 82172         55130 my $radix = $self->{'radix'};
106 82172 50       89425 if ($radix < 7) {
107 0         0 return 0; # no digit 6s at all if radix<7
108             }
109 82172 100       86623 if ($radix == 10) {
110 58060         103142 return ($value =~ /666/);
111             }
112              
113 24112 50       29000 if (_is_infinite($value)) {
114 0         0 return 0;
115             }
116              
117 24112         19451 my $cube = $self->{'cube'}; # radix^3
118 24112         14838 my $target = $self->{'target'}; # 666 in radix
119 24112         13697 for (;;) {
120 64109 100       71158 if (($value % $cube) == $target) {
121 137         208 return 1;
122             }
123 63972 100       65002 if ($value < $cube) {
124 23975         31776 return 0;
125             }
126 39997         26336 $value = int($value/$radix);
127             }
128             }
129              
130             1;
131             __END__