{ my @primes = (2, 3); my %primes = (2 => 2, 3 => 3); my %memo; my $_is_prime = sub { my $posit = shift; my $sqrtp = sqrt($posit); for my $p (@primes) { last if $p > $sqrtp; return 0 unless $posit % $p; } return 1; }; my $_fill = sub { my $bar = int sqrt(shift); for (my $last = $primes[-1] + 2; $primes[-1] < $bar; $last += 2) { if (exists $memo{$last} and $memo{$last}) { push @primes, $primes{$last} = delete $memo{$last}; } else { push @primes, $primes{$last} = $last if $_is_prime->($last); } } }; my $_purge = sub { foreach (keys %memo) { if ($_ < $primes[-1]) { delete $memo{$_}; } } }; sub is_prime { my $posit = shift; if ($primes[-1] < $posit) { return $memo{$posit} if exists $memo{$posit}; $_fill->($posit); $_purge->(); return $memo{$posit} = $_is_prime->($posit) ? $posit : 0; } else { return exists $primes{$posit}; } } }