Skip to content

Instantly share code, notes, and snippets.

@BenGoldberg1
Last active July 31, 2016 18:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BenGoldberg1/147f6ec10c0f4428f7767baa8ae9c15a to your computer and use it in GitHub Desktop.
Save BenGoldberg1/147f6ec10c0f4428f7767baa8ae9c15a to your computer and use it in GitHub Desktop.
use v6;
constant DEBUGGING = False;
my class P does Iterator {
has @!outbuf;
has $!wheel-size;
has @!surely-composite;
has @!wheel-indices;
has @!primes;
has @!composite;
has $!batch-start = 0;
has $!first-start-ix;
has $!a-prime;
has $!a-squared-prime;
submethod BUILD {
@!outbuf = (2, 3, 5);
$!wheel-size = [*] @!outbuf;
@!surely-composite = (^$!wheel-size).map: -> $ix { !@!outbuf.first: -> $prime { $ix %% $prime } };
@!wheel-indices = (^$!wheel-size).grep: { @!surely-composite[$_] };
#"The wheel test array has {+@!surely-composite} elements".say if DEBUGGING;
"The wheel indices array has @!wheel-indices[] elements".say if DEBUGGING;
$!first-start-ix = -1;
repeat {
repeat {
++$!first-start-ix;
} while @!wheel-indices[$!first-start-ix] <= @!outbuf[*-1];
$!a-prime = @!wheel-indices[$!first-start-ix];
$!a-squared-prime = $!a-prime ** 2;
} until @!surely-composite[ $!a-squared-prime % $!wheel-size ];
if $!first-start-ix < 0 {
die "repeat...until does not do what i think it does"
}
}
method !mark-next-multiple( \factor ) {
my $where = factor;
$where += factor while @!composite[$where] || @!surely-composite[ $where % $!wheel-size ];
@!composite[ $where ] = factor;
}
method pull-one {
until @!outbuf {
for ($!first-start-ix ..^ @!wheel-indices) {
my $maybe-prime = $!batch-start + @!wheel-indices[$_];
if @!composite[$_] -> \factor {
"$maybe-prime is a multiple of {factor}".say if DEBUGGING;
self!mark-next-multiple: factor;
} elsif $maybe-prime < $!a-squared-prime {
say "$maybe-prime is prime" if DEBUGGING;
@!primes.push: $maybe-prime;
@!outbuf.push: $maybe-prime;
"There are {+@!primes} enqueued primes".say if DEBUGGING;
} elsif $maybe-prime == $!a-squared-prime {
"$maybe-prime is a square".say if DEBUGGING;
"There were {+@!primes} enqueued primes".say if DEBUGGING;
self!mark-next-multiple: $!a-prime;
$!a-prime = @!primes.shift;
$!a-squared-prime = $!a-prime * $!a-prime;
} elsif @!surely-composite[ $!a-squared-prime % $!wheel-size ] {
print "[$maybe-prime>$!a-squared-prime] ";
self!mark-next-multiple: $!a-prime;
$!a-prime = @!primes.shift;
$!a-squared-prime = $!a-prime * $!a-prime;
redo;
} else {
die "Critical math failure: Programmer or compiler is innumerate. $maybe-prime > $!a-squared-prime";
}
}
$!first-start-ix = 0;
$!batch-start += $!wheel-size;
@!composite.splice: 0, $!wheel-size;
}
return @!outbuf.shift;
}
method is-lazy { True }
method count-only { Inf }
};
my $howlong = @*ARGS ?? @*ARGS.shift !! 3;
my $end = $howlong + time;
my $prior = 1;
for Seq.new(P.new) -> $p {
"$p ".print;
if ( grep *.is-prime, $prior ^..^ $p ) -> @uh-oh {
die "Skpped a prime, @uh-oh[]" if @uh-oh.elems == 1;
die "Skipped some primes, @uh-oh[]";
}
die "Not prime!" unless $p.is-prime;
$prior = $p;
last if time >= $end;
}
say '';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment