| 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::RepdigitAny; | 
| 19 | 2 |  |  | 2 |  | 6854 | use 5.004; | 
|  | 2 |  |  |  |  | 4 |  | 
| 20 | 2 |  |  | 2 |  | 6 | use strict; | 
|  | 2 |  |  |  |  | 2 |  | 
|  | 2 |  |  |  |  | 39 |  | 
| 21 |  |  |  |  |  |  |  | 
| 22 | 2 |  |  | 2 |  | 6 | use vars '$VERSION', '@ISA'; | 
|  | 2 |  |  |  |  | 2 |  | 
|  | 2 |  |  |  |  | 94 |  | 
| 23 |  |  |  |  |  |  | $VERSION = 72; | 
| 24 | 2 |  |  | 2 |  | 347 | use Math::NumSeq 7; # v.7 for _is_infinite() | 
|  | 2 |  |  |  |  | 21 |  | 
|  | 2 |  |  |  |  | 77 |  | 
| 25 |  |  |  |  |  |  | @ISA = ('Math::NumSeq'); | 
| 26 |  |  |  |  |  |  | *_is_infinite = \&Math::NumSeq::_is_infinite; | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  | # uncomment this to run the ### lines | 
| 29 |  |  |  |  |  |  | #use Smart::Comments; | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  |  | 
| 32 |  |  |  |  |  |  | # use constant name => Math::NumSeq::__('Repdigit Any Radix'); | 
| 33 | 2 |  |  | 2 |  | 7 | use constant description => Math::NumSeq::__('Numbers which are a "repdigit" like 1111, 222, 999 etc of 3 or more digits in some number base.'); | 
|  | 2 |  |  |  |  | 3 |  | 
|  | 2 |  |  |  |  | 5 |  | 
| 34 | 2 |  |  | 2 |  | 7 | use constant i_start => 1; | 
|  | 2 |  |  |  |  | 3 |  | 
|  | 2 |  |  |  |  | 72 |  | 
| 35 | 2 |  |  | 2 |  | 9 | use constant values_min => 0; | 
|  | 2 |  |  |  |  | 2 |  | 
|  | 2 |  |  |  |  | 89 |  | 
| 36 | 2 |  |  | 2 |  | 7 | use constant characteristic_increasing => 1; | 
|  | 2 |  |  |  |  | 3 |  | 
|  | 2 |  |  |  |  | 66 |  | 
| 37 | 2 |  |  | 2 |  | 6 | use constant characteristic_integer => 1; | 
|  | 2 |  |  |  |  | 2 |  | 
|  | 2 |  |  |  |  | 67 |  | 
| 38 |  |  |  |  |  |  |  | 
| 39 |  |  |  |  |  |  | # cf A167783 - length >=2, 2 or more bases | 
| 40 |  |  |  |  |  |  | #    A053696 - length >=3, 1 or more bases repunit | 
| 41 |  |  |  |  |  |  | # | 
| 42 |  |  |  |  |  |  | #    A158235 - square is a repdigit in some base < i | 
| 43 |  |  |  |  |  |  | #    A158236 - the radix for those squares | 
| 44 |  |  |  |  |  |  | #    A158237 - those squares, ie. squares which are repdigits some base | 
| 45 |  |  |  |  |  |  | #    A158245 - "primitives" in squares seq, meaning square-free | 
| 46 |  |  |  |  |  |  | # | 
| 47 | 2 |  |  | 2 |  | 5 | use constant oeis_anum => 'A167782'; # length >=3, 1 or more bases | 
|  | 2 |  |  |  |  | 2 |  | 
|  | 2 |  |  |  |  | 678 |  | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | sub rewind { | 
| 50 | 4 |  |  | 4 | 1 | 364 | my ($self) = @_; | 
| 51 | 4 |  |  |  |  | 19 | $self->{'i'} = $self->i_start; | 
| 52 | 4 |  |  |  |  | 4 | $self->{'done'} = 0; | 
| 53 | 4 |  |  |  |  | 9 | $self->{'ones'}   = [ undef, undef, 7 ]; | 
| 54 | 4 |  |  |  |  | 12 | $self->{'digits'} = [ undef, undef, 1 ]; | 
| 55 |  |  |  |  |  |  | } | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | sub next { | 
| 58 | 25 |  |  | 25 | 1 | 431 | my ($self) = @_; | 
| 59 |  |  |  |  |  |  | ### RepdigitAny next(): $self->{'i'} | 
| 60 |  |  |  |  |  |  |  | 
| 61 | 25 |  |  |  |  | 18 | my $done; | 
| 62 | 25 | 100 |  |  |  | 33 | if ($done = $self->{'done'}) { | 
| 63 | 22 |  |  |  |  | 21 | my $min = $done*$done + 7; | 
| 64 | 22 |  |  |  |  | 14 | my $ones = $self->{'ones'}; | 
| 65 | 22 |  |  |  |  | 17 | my $digits = $self->{'digits'}; | 
| 66 |  |  |  |  |  |  |  | 
| 67 | 22 |  |  |  |  | 18 | for (my $radix = 2; ; $radix++) { | 
| 68 |  |  |  |  |  |  | ### $radix | 
| 69 |  |  |  |  |  |  |  | 
| 70 | 86 |  |  |  |  | 47 | my $one; | 
| 71 | 86 | 100 |  |  |  | 77 | if ($radix > $#$ones) { | 
| 72 |  |  |  |  |  |  | ### maybe extend array: $radix | 
| 73 | 33 |  |  |  |  | 24 | $one = ($radix + 1) * $radix + 1; | 
| 74 | 33 | 100 |  |  |  | 43 | if ($one > $min) { | 
| 75 |  |  |  |  |  |  | ### stop at big one: $one | 
| 76 | 22 |  |  |  |  | 17 | last; | 
| 77 |  |  |  |  |  |  | } | 
| 78 | 11 |  |  |  |  | 16 | $ones->[$radix] = $one; | 
| 79 | 11 |  |  |  |  | 10 | $digits->[$radix] = 1; | 
| 80 |  |  |  |  |  |  | } else { | 
| 81 | 53 |  |  |  |  | 37 | $one = $ones->[$radix]; | 
| 82 |  |  |  |  |  |  | } | 
| 83 |  |  |  |  |  |  |  | 
| 84 | 64 |  |  |  |  | 38 | my $repdigit; | 
| 85 | 64 |  |  |  |  | 83 | while (($repdigit = $one * $digits->[$radix]) <= $done) { | 
| 86 |  |  |  |  |  |  | ### increase past done: $repdigit | 
| 87 | 20 | 100 |  |  |  | 32 | if (++$digits->[$radix] >= $radix) { | 
| 88 | 10 |  |  |  |  | 8 | $digits->[$radix] = 1; | 
| 89 | 10 |  |  |  |  | 19 | $one = $ones->[$radix] = $ones->[$radix] * $radix + 1; | 
| 90 |  |  |  |  |  |  | ### digit wrap new ones: $ones->[$radix] | 
| 91 |  |  |  |  |  |  | } else { | 
| 92 |  |  |  |  |  |  | ### digit step: $digits->[$radix] | 
| 93 |  |  |  |  |  |  | } | 
| 94 |  |  |  |  |  |  | } | 
| 95 |  |  |  |  |  |  |  | 
| 96 |  |  |  |  |  |  | ### consider repdigit: $repdigit | 
| 97 | 64 | 100 |  |  |  | 75 | if ($repdigit < $min) { | 
| 98 |  |  |  |  |  |  | ### min now: "$repdigit at $radix" | 
| 99 | 40 |  |  |  |  | 27 | $min = $repdigit; | 
| 100 |  |  |  |  |  |  | } | 
| 101 |  |  |  |  |  |  | } | 
| 102 |  |  |  |  |  |  | ### result: $min | 
| 103 | 22 |  |  |  |  | 16 | $self->{'done'} = $min; | 
| 104 | 22 |  |  |  |  | 33 | return ($self->{'i'}++, $min); | 
| 105 |  |  |  |  |  |  |  | 
| 106 |  |  |  |  |  |  | } else { | 
| 107 |  |  |  |  |  |  | # special case value 0 | 
| 108 | 3 |  |  |  |  | 3 | $self->{'done'} = 1; | 
| 109 | 3 |  |  |  |  | 8 | return ($self->{'i'}++, 0); | 
| 110 |  |  |  |  |  |  | } | 
| 111 |  |  |  |  |  |  | } | 
| 112 |  |  |  |  |  |  |  | 
| 113 |  |  |  |  |  |  | sub pred { | 
| 114 | 70 |  |  | 70 | 1 | 221 | my ($self, $value) = @_; | 
| 115 |  |  |  |  |  |  | ### RepdigitAny pred(): $value | 
| 116 |  |  |  |  |  |  |  | 
| 117 | 70 | 100 |  |  |  | 81 | if ($value == 0) { | 
| 118 | 2 |  |  |  |  | 3 | return 1; | 
| 119 |  |  |  |  |  |  | } | 
| 120 | 68 | 100 | 66 |  |  | 97 | if (_is_infinite($value) || $value != int($value)) { | 
| 121 | 31 |  |  |  |  | 31 | return 0; | 
| 122 |  |  |  |  |  |  | } | 
| 123 |  |  |  |  |  |  |  | 
| 124 | 37 |  |  |  |  | 27 | RADIX: for (my $radix = 2; ; $radix++) { | 
| 125 | 86 |  |  |  |  | 64 | my $ones = ($radix + 1) * $radix + 1; | 
| 126 | 86 | 100 |  |  |  | 93 | if ($ones > $value) { | 
| 127 | 25 |  |  |  |  | 25 | return 0; | 
| 128 |  |  |  |  |  |  | } | 
| 129 |  |  |  |  |  |  |  | 
| 130 | 61 |  |  |  |  | 37 | do { | 
| 131 | 84 | 100 |  |  |  | 89 | if ($ones == $value) { | 
| 132 | 10 |  |  |  |  | 10 | return 1; | 
| 133 |  |  |  |  |  |  | } | 
| 134 | 74 |  |  |  |  | 69 | foreach my $digit (2 .. $radix-1) { | 
| 135 | 26 |  |  |  |  | 16 | my $repdigit = $digit * $ones; | 
| 136 | 26 | 100 |  |  |  | 30 | if ($repdigit == $value) { | 
| 137 | 2 |  |  |  |  | 5 | return 1; | 
| 138 |  |  |  |  |  |  | } | 
| 139 | 24 | 100 |  |  |  | 30 | if ($repdigit > $value) { | 
| 140 | 20 |  |  |  |  | 19 | next RADIX; | 
| 141 |  |  |  |  |  |  | } | 
| 142 |  |  |  |  |  |  | } | 
| 143 | 52 |  |  |  |  | 75 | $ones = $ones * $radix + 1; | 
| 144 |  |  |  |  |  |  | } while ($ones <= $value); | 
| 145 |  |  |  |  |  |  | } | 
| 146 |  |  |  |  |  |  | } | 
| 147 |  |  |  |  |  |  |  | 
| 148 |  |  |  |  |  |  | 1; | 
| 149 |  |  |  |  |  |  | __END__ |