ETOOBUSY 🚀 minimal blogging for the impatient
PWC167 - Circular Prime
TL;DR
Here we are with TASK #1 from The Weekly Challenge #167. Enjoy!
The challenge
Write a script to find out first
10 circular primes
having at least 3 digits (base 10).Please checkout wikipedia for more information.
A circular prime is a prime number with the property that the number generated at each intermediate step when cyclically permuting its (base 10) digits will also be prime.
Output
113, 197, 199, 337, 1193, 3779, 11939, 19937, 193939, 199933
The questions
Something that is not specified is that only the lowest value in a set of rotations should be considered. Right? I mean, 131 is a circular prime too, but if we print out 113 then we skip it.
The solution
It’s bare bones string manipulation and tests for primality all the way down:
#!/usr/bin/env raku
use v6;
subset PosInt where * > 0;
sub MAIN (PosInt:D $n is copy = 10) {
my $x = 99;
my @result = gather while $n > 0 {
if is-circular-prime($x) {
take $x;
--$n;
}
$x += 2;
}
@result.join(', ').put;
}
sub is-circular-prime ($x is copy) {
my $initial = $x;
for 1 ..^ $x.chars {
return False unless $x.is-prime;
$x = $x.substr(*-1, 1) ~ $x.substr(0, *-1);
return False if $x < $initial;
}
return $x.is-prime;
}
And, of course, the Perl version. Here we’re taking advantage of ntheory to iterate through primes only natively:
#!/usr/bin/env perl
use v5.24;
use warnings;
use experimental 'signatures';
no warnings 'experimental::signatures';
use File::Basename 'dirname';
use lib dirname(__FILE__) . '/local/lib/perl5';
use ntheory qw< next_prime is_prime >;
my $n = shift // 10;
my @retval;
my $candidate = 100;
while ($n > 0) {
$candidate = next_prime($candidate);
next unless is_circular_prime($candidate);
push @retval, $candidate;
--$n;
}
say join ', ', @retval;
sub is_circular_prime ($x) {
my $initial = $x;
for (2 .. length $x) {
return !!0 unless is_prime($x);
$x = substr($x, 1) . substr($x, 0, 1);
return !!0 if $x < $initial;
}
return is_prime($x);
}
Stay safe!