Last active
July 31, 2016 18:24
-
-
Save BenGoldberg1/147f6ec10c0f4428f7767baa8ae9c15a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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