1193 is 'rotationally prime' because 1193 and all of it's
rotations (1931, 9311, and 3119) are prime. There is
another set of 4-digit, and two sets of 5-digit rot-prime
numbers. I think that's cool, but I'm not sure why...
Update: changed stop criteria in sub primelist from
test/2 to sqrt(test). Thanks to larsen.
Also, there are two sets of 6 digit rot-prime numbers.
YuckFoo
#!/usr/bin/perl
use strict;
my ($DIGITS) = (5);
my ($list, $item);
$list = primelist(10**$DIGITS);
$list = rotatelist($list);
for $item (@{$list}) { print "$item\n"; }
#-----------------------------------------------------------
sub rotatelist {
my ($primes) = @_;
my (@list, %phash, $prime, $sum);
my ($rotations, $rotation);
@phash{@{$primes}} = (1) x @{$primes};
for $prime (@{$primes}) {
$rotations = rotations($prime);
if ($prime == $rotations->[0]) {
$sum = 0;
for $rotation (@{$rotations}) {
$sum += $phash{$rotation};
}
if ($sum == @{$rotations}) { push (@list, $prime); }
}
}
return \@list;
}
#-----------------------------------------------------------
sub rotations {
my ($num) = @_;
my (@list, @digs, $i);
@digs = split('', $num);
for ($i = 0; $i < length($num); $i++) {
push (@digs, shift(@digs));
push (@list, join ('', @digs) + 0);
}
@list = sort(@list);
return \@list;
}
#-----------------------------------------------------------
sub primelist {
my ($max) = @_;
my ($test, $stop, $isprime, $prime);
my (@primes) = qw(2);
for ($test = 3; $test < $max; $test++) {
$stop = sqrt($test);
$isprime = 1;
for $prime (@primes) {
if ($prime > $stop) { last; }
if ($test % $prime == 0) {
$isprime = 0;
last;
}
}
if ($isprime) { push (@primes, $test); }
}
return \@primes;
}
Re: Rotationally Prime Numbers
by particle (Vicar) on Jan 29, 2002 at 04:32 UTC
|
i wrote an algorithm to save you many, many cycles.
createPrimeVec() creates a bit vector of length $max. the value is 0 if prime, 1 otherwise. it uses the sieve of erathosthenes method to create the list. merlyn wrote a column on this some time ago (suprise!)
isprime() is a simple bit vector lookup, very fast.
rotPrime() cleverly appends the return value of chop to the beginning of the string.
here it is:
#!/usr/local/bin/perl -w
use strict;
$|=1;
my $vecPrime;
my %rotPrime;
# allows specification of a range, such as (1000, 9999)
my ($min, $max) = (2, 999_999);
print "---creating prime vector (length: $max)\n";
$vecPrime = createPrimeVec($max);
print "---created\n\n";
print "---trying rotations $min..$max\n";
for($min..$max) {
next unless isprime($_);
my $x = rotPrime($_);
$x && $rotPrime{$x}++;
}
print "---tried $min..$max\n\n";
print "$_\n" for(sort {$a <=> $b} keys %rotPrime);
#----------
# return list of prime numbers up to and including value passed (defau
+lt:1000)
sub createPrimeVec {
my $UPPER = shift || 1000;
my $sieve = "";
GUESS: for (my $guess = 2; $guess <= $UPPER; $guess++) {
next GUESS if vec($sieve,$guess,1);
for(my $mults = $guess * $guess; $mults <= $UPPER; $mults += $
+guess) {
vec($sieve,$mults,1) = 1;
} }
return $sieve;
};
# returns true if found in prime number bit vector
sub isprime { return 1 if( vec($vecPrime,shift,1) == 0 ); };
# return smallest 'rotationally prime' number in set
# for instance, 1931, 9311, 3119, or 1193 yeilds return value 1193
sub rotPrime {
my ($num, $lchr, @list) = (shift);
for(1..length $num) {
$lchr = chop $num;
$num = $lchr . $num;
push @list, $num;
return unless isprime($num);
}
return (sort @list)[0];
};
i had used the prime number code for a program using fermat's factoring algorithm. perhaps i'll post it, assuming there's not a module to do that already.
~Particle
| [reply] [d/l] |
|
| [reply] |
|
i had used the prime number code for a program using fermat's factoring algorithm. perhaps i'll post it, assuming there's not a module to do that already.
Surely there was space in the margin to post it :-)
| [reply] |
Re: Rotationally Prime Numbers
by dragonchild (Archbishop) on Jan 29, 2002 at 03:14 UTC
|
Neat algorithm. I'll arrogantly rewrite your code to make it what I consider to be more Perlish. :-)
This takes advantage of a number of things some C/C++ programmers may or may not know/be comfortable with.
#!/usr/local/bin/perl
use strict;
use warnings;
use constant DIGITS => (5);
my $list = primelist(10 ** DIGITS);
$list = rotatelist($list);
print $_, $/ for @$list;
#-----------------------------------------------------------
sub rotatelist {
my ($primes) = @_;
my %phash;
@phash{@{$primes}} = (1) x @{$primes};
my @list;
for my $prime (@{$primes}) {
my $rotations = rotations($prime);
if ($prime == $rotations->[0]) {
my $sum = 0;
$sum += $phash{$_} || 0 for @$rotations;
push @list, $prime
if $sum == @{$rotations};
}
}
return \@list;
}
#-----------------------------------------------------------
sub rotations {
my ($num) = @_;
my @digs = split '', $num;
my @list;
for (1 .. length($num)) {
push @digs, shift @digs;
push @list, join ('', @digs) + 0;
}
@list = sort(@list);
return \@list;
}
#-----------------------------------------------------------
sub primelist {
my ($max) = @_;
my @primes = (2);
for (my $test = 3; $test < $max; $test += 2) {
my $stop = sqrt($test);
my $isprime = 1;
for my $prime (@primes) {
last if $prime >= $stop;
if ($test % $prime == 0) {
$isprime = 0;
last;
}
}
push @primes, $test if $isprime;
}
return \@primes;
}
------ We are the carpenters and bricklayers of the Information Age. Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement. | [reply] [d/l] |
Re (tilly) 1: Rotationally Prime Numbers
by tilly (Archbishop) on Feb 01, 2002 at 04:00 UTC
|
A minor number theory note.
Based on some back of the envelope estimates, there should
be only a finite number of rotational primes in base 10.
(I haven't double-checked my estimates closely, but I find
it suggestive that you have 4 of size 1, and none of size
7.)
However my estimates suggesting this were based on the
standard, "Treat is_prime(n) as a random number with
probability 1/log(n) of being true." This is a simple
rule of thumb which leads to a lot of estimates in number
theory, most of which are strongly supported by the
numerical evidence. (For instance the prime number theorem
is true, the Riemann Hypothesis should be, the twin
prime conjecture should be, Mertens Conjecture should be
false but the numerical evidence will make it look true
for an absurdly long time, etc.)
Unfortunately it is a rule of thumb that is absolutely and
horribly wrong, with the result that number theory is full
of gloriously precise conjectures on primes which have very
strong affirmative evidence, but which are not readily
amenable to proof.
UPDATE: As I point out at Re^2: Rotationally Prime Numbers Revisited, I think this post is wrong. (I forgot about numbers that are just strings of 1s.) | [reply] |
|
| [reply] |
Re: Rotationally Prime Numbers
by Anonymous Monk on Jan 31, 2002 at 19:36 UTC
|
You should be able to get a fairly decent speed improvement by automatically throwing out any numbers containing a 0, 2, 4, 5, 6 or 8 as obviously these can't be rotationally prime.
Hadley
| [reply] |
Re: Rotationally Prime Numbers
by trammell (Priest) on Feb 01, 2002 at 00:11 UTC
|
There was a great thread on CLPM where Abigail posted some super sieve code.
http://groups.google.com/groups?q=abigail+sieve+group:comp.lang.perl.misc+group:comp.lang.perl.misc&hl=en&scoring=d
| [reply] |
|
|