File Coverage

blib/lib/Acme/PERLANCAR/Prime.pm
Criterion Covered Total %
statement 42 44 95.4
branch 10 14 71.4
condition 1 3 33.3
subroutine 7 8 87.5
pod 1 1 100.0
total 61 70 87.1


line stmt bran cond sub pod time code
1             package Acme::PERLANCAR::Prime;
2              
3             our $DATE = '2016-09-23'; # DATE
4             our $DIST = 'Acme-PERLANCAR-Prime'; # DIST
5             our $VERSION = '0.001'; # VERSION
6              
7 1     1   13469 use 5.010001;
  1         3  
8 1     1   449 use integer;
  1         7  
  1         4  
9 1     1   22 use strict;
  1         1  
  1         17  
10 1     1   2 use warnings;
  1         1  
  1         24  
11              
12 1     1   2 use Exporter qw(import);
  1         1  
  1         257  
13             our @EXPORT_OK = qw(primes);
14              
15             my @primes = (2);
16              
17             sub _empty_cache {
18 0     0   0 @primes = (2);
19             }
20              
21             sub _is_prime {
22 4     4   2 my $num = shift;
23 4         18 my $sqrt = $num**0.5;
24 4         5 for my $i (0..$#primes) {
25 7         8 my $fact = $primes[$i];
26 7 100       8 last if $fact > $sqrt;
27 4 100       8 return 0 if $num % $fact == 0;
28             }
29 3         5 1;
30             }
31              
32             sub primes {
33 1     1 1 6 my ($base, $num);
34              
35 1 50       3 if (@_ > 1) {
36 0         0 ($base, $num) = @_;
37             } else {
38 1         1 $base = 1;
39 1         2 $num = $_[0];
40             }
41              
42 1         1 my @res;
43 1         2 my $i = $base;
44 1 50       3 $i = 2 if $i < 2;
45              
46             # first, fill with precomputed primes
47 1         2 my $k = -1;
48 1         3 for my $j (0..$#primes) {
49 1         1 my $p = $primes[$j];
50 1 50 33     9 if ($p >= $i && $p <= $num) {
51 1         2 push @res, $p;
52 1         1 $i = $p + 1;
53 1         3 $k = $j;
54             }
55             }
56              
57 1         3 while ($i <= $num) {
58 4 100       5 if (_is_prime($i)) {
59 3         4 push @primes, $i;
60 3         2 push @res, $i;
61             }
62 4         2 $i++;
63 4 50       10 $i++ if $i % 2 == 0; # quick skip even numbers
64             }
65 1         7 @res;
66             }
67              
68             1;
69             # ABSTRACT: Return prime numbers
70              
71             __END__