1package Math::Prime::Util::PrimeIterator; 2use strict; 3use warnings; 4 5BEGIN { 6 $Math::Prime::Util::PrimeIterator::AUTHORITY = 'cpan:DANAJ'; 7 $Math::Prime::Util::PrimeIterator::VERSION = '0.73'; 8} 9 10use base qw( Exporter ); 11our @EXPORT_OK = qw( ); 12our %EXPORT_TAGS = (all => [ @EXPORT_OK ]); 13 14 15use Math::Prime::Util qw/next_prime prev_prime is_prime prime_count nth_prime/; 16 17# We're going to use a scalar rather than a hash because there is currently 18# only one data object (the current value) and this makes it little faster. 19 20sub new { 21 my ($class, $start) = @_; 22 my $p = 2; 23 my $self = bless \$p, $class; 24 $self->rewind($start) if defined $start; 25 return $self; 26} 27 28# To make Iterator::Simple happy. 29sub __iter__ { 30 my $self = shift; 31 require Iterator::Simple; 32 return Iterator::Simple::iterator(sub { $self->iterate }); 33 $self; 34} 35 36sub value { ${$_[0]}; } 37sub next { 38 #my $self = shift; $$self = next_prime($$self); return $self; 39 ${$_[0]} = next_prime(${$_[0]}); 40 return $_[0]; 41} 42sub prev { 43 my $self = shift; 44 my $p = $$self; 45 $$self = ($p <= 2) ? 2 : prev_prime($p); 46 return $self; 47} 48sub iterate { 49 #my $self = shift; my $p = $$self; $$self = next_prime($p); return $p; 50 my $p = ${$_[0]}; 51 ${$_[0]} = next_prime(${$_[0]}); 52 return $p; 53} 54 55sub rewind { 56 my ($self, $start) = @_; 57 $$self = 2; 58 if (defined $start && $start ne '2') { 59 Math::Prime::Util::_validate_num($start) 60 || Math::Prime::Util::_validate_positive_integer($start); 61 $$self = next_prime($start-1) if $start > 2; 62 } 63 return $self; 64} 65 66sub peek { 67 return next_prime(${$_[0]}); 68} 69 70# Some methods to match Math::NumSeq 71sub tell_i { 72 return prime_count(${$_[0]}); 73} 74sub pred { 75 my($self, $n) = @_; 76 return is_prime($n); 77} 78sub ith { 79 my($self, $n) = @_; 80 return nth_prime($n); 81} 82sub seek_to_i { 83 my($self, $n) = @_; 84 $self->rewind( nth_prime($n) ); 85} 86sub seek_to_value { 87 my($self, $n) = @_; 88 $self->rewind($n); 89} 90sub value_to_i { 91 my($self, $n) = @_; 92 return unless is_prime($n); 93 return prime_count($n); 94} 95sub value_to_i_ceil { 96 my($self, $n) = @_; 97 return prime_count(next_prime($n-1)); 98} 99sub value_to_i_floor { 100 my($self, $n) = @_; 101 return prime_count($n); 102} 103sub value_to_i_estimate { 104 my($self, $n) = @_; 105 return Math::Prime::Util::prime_count_approx($n); 106} 107sub i_start { 1 } 108sub description { "The prime numbers 2, 3, 5, 7, 11, 13, 17, etc." } 109sub values_min { 2 } 110sub values_max { undef } 111sub oeis_anum { "A000040" } 1121; 113 114__END__ 115 116 117# ABSTRACT: An object iterator for primes 118 119=pod 120 121=for stopwords prev pred ith i'th 122 123=for test_synopsis use v5.14; my ($i,$n) = (2,2); 124 125=head1 NAME 126 127Math::Prime::Util::PrimeIterator - An object iterator for primes 128 129 130=head1 VERSION 131 132Version 0.73 133 134 135=head1 SYNOPSIS 136 137 use Math::Prime::Util::PrimeIterator; 138 my $it = Math::Prime::Util::PrimeIterator->new(); 139 140 # Simple use: return current value and move forward. 141 my $sum = 0; $sum += $it->iterate() for 1..10000; 142 143 # Methods 144 my $v = $it->value(); # Return current value 145 $it->next(); # Move to next prime (returns self) 146 $it->prev(); # Move to prev prime (returns self) 147 $v = $it->iterate(); # Returns current value; moves to next prime 148 $it->rewind(); # Resets position to 2 149 $it->rewind($n); # Resets position to next_prime($n-1) 150 151 # Methods similar to Math::NumSeq, do not change iterator 152 $it->tell_i(); # Returns the index of the current position 153 $it->pred($n); # Returns true if $n is prime 154 $it->ith($i); # Returns the $ith prime 155 $it->value_to_i($n); # Returns the index of the first prime >= $n 156 $it->value_to_i_estimate($n); # Approx index of value $n 157 158 # Methods similar to Math::NumSeq, changes iterator 159 $it->seek_to_i($i); # Resets position to the $ith prime 160 $it->seek_to_value($i); # Resets position to next_prime($i-1) 161 162=head1 DESCRIPTION 163 164An iterator over the primes. L</new> returns an iterator object and takes 165an optional starting position (the initial value will be the least prime 166greater than or equal to the argument). BigInt objects will be returned if 167the value overflows a Perl unsigned integer value. 168 169=head1 METHODS 170 171=head2 new 172 173Creates an iterator object with initial value of 2. If an argument is 174given, the initial value will be the least prime greater than or equal 175to the argument. 176 177=head2 value 178 179Returns the value at the current position. Will always be a prime. If 180the value is greater than ~0, it will be a L<Math::BigInt> object. 181 182=head2 next 183 184Moves the current position to the next prime. 185Returns self so calls can be chained. 186 187=head2 prev 188 189Moves the current position to the previous prime, unless the current 190value is 2, in which case the value remains 2. 191Returns self so calls can be chained. 192 193=head2 iterate 194 195Returns the value at the current position and also moves the position to 196the next prime. 197 198=head2 rewind 199 200Resets the current position to either 2 or, if given an integer argument, 201the least prime not less than the argument. 202 203=head2 peek 204 205Returns the value at the next position without moving the iterator. 206 207=head2 tell_i 208 209Returns the index of the current position, starting at 1 (corresponding to 210the value 2). 211The iterator is unchanged after this call. 212 213=head2 pred 214 215Returns true if the argument is a prime, false otherwise. 216The iterator is unchanged after this call. 217 218=head2 ith 219 220Returns the i'th prime, where the first prime is 2. 221The iterator is unchanged after this call. 222 223=head2 value_to_i_estimate 224 225Returns an estimate of the index corresponding to the argument. That is, 226given a value C<n>, we expect a prime approximately equal to C<n> to occur 227at this index. 228 229The estimate is performed using L<Math::Prime::Util/prime_count_approx>, 230which uses the estimates of Dusart 2010 (or better for small values). 231 232=head2 value_to_i 233 234If the argument is prime, returns the corresponding index, such that: 235 236 ith( value_to_i( $n ) ) == $n 237 238Returns C<undef> if the argument is not prime. 239 240=head2 value_to_i_floor 241 242=head2 value_to_i_ceil 243 244Returns the index corresponding to the first prime less than or equal 245to the argument, or greater than or equal to the argument, respectively. 246 247=head2 seek_to_i 248 249Resets the position to the prime corresponding to the given index. 250 251=head2 seek_to_value 252 253An alias for L</rewind>. 254 255=head2 i_start 256=head2 description 257=head2 values_min 258=head2 values_max 259=head2 oeis_anum 260 261Methods to match Math::NumSeq::Primes. 262 263=head1 SEE ALSO 264 265L<Math::Prime::Util> 266 267L<Math::Prime::Util/forprimes> 268 269L<Math::Prime::Util/prime_iterator> 270 271L<Math::Prime::Util/prime_iterator_object> 272 273L<Math::Prime::Util::PrimeArray> 274 275L<Math::NumSeq::Primes> 276 277L<List::Gen> 278 279=head1 AUTHORS 280 281Dana Jacobsen E<lt>dana@acm.orgE<gt> 282 283 284=head1 COPYRIGHT 285 286Copyright 2013 by Dana Jacobsen E<lt>dana@acm.orgE<gt> 287 288This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. 289 290=cut 291