aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-144/james-smith/perl/ch-1.pl55
-rw-r--r--challenge-144/james-smith/perl/ch-2.pl44
2 files changed, 89 insertions, 10 deletions
diff --git a/challenge-144/james-smith/perl/ch-1.pl b/challenge-144/james-smith/perl/ch-1.pl
index 97fe5b4e33..39a78002de 100644
--- a/challenge-144/james-smith/perl/ch-1.pl
+++ b/challenge-144/james-smith/perl/ch-1.pl
@@ -8,16 +8,55 @@ use Test::More;
use Benchmark qw(cmpthese timethis);
use Data::Dumper qw(Dumper);
+my($C,$I) = (100,100_000);
+#say foreach sp_loop(100);exit;
+cmpthese( 100, {
+ 'sp' => sub { semiprimes($I); },
+ 'sl' => sub { sp_loop( $I); },
+ 'sm' => sub { sp_map( $I); },
+});
-my $N = 1000;
-my @primes = (2);
-my @semi_primes = (4);
+sub sp_loop {
+ my $N = shift;
+ my @p; my %ph;
+ my @sp;
+ foreach my $t ( 2..$N ) {
+ my $prime = 1;
+ foreach(@p) {
+ next if $t%$_;
+ $prime = 0;
+ (push @sp,$t) && (last) if exists $ph{$t/$_};
+ }
+ if( $prime ) {
+ push @p,$t; $ph{$t}=1;
+ }
+ }
+ @sp;
+}
+
+sub sp_map {
+ my $N = shift;
+ my @primes = (2);
+ my @semi_primes = (4);
-foreach my $p ( map { 1+2*$_ } 1..($N/4) ) {
- map { ($p%$_)||(next) } @primes;
- push @primes,$p;
- push @semi_primes,grep {$_<=$N} map{$p*$_} @primes;
+ foreach my $p ( map { 1+2*$_ } 1..($N/4) ) {
+ map { ($p%$_)||(next) } @primes;
+ push @primes,$p;
+ push @semi_primes,grep {$_<=$N} map{$p*$_} @primes;
+ }
+ sort {$a<=>$b} @semi_primes;
}
-say for sort {$a<=>$b} @semi_primes;
+sub semiprimes {
+ my $N = shift;
+ my @primes = (2);
+ my @semi_primes = (4);
+
+ foreach my $p ( map { 1+2*$_ } 1..($N/4) ) {
+ map { ($p%$_)||(next) } @primes;
+ push @primes,$p;
+ ($p*$_>$N) ? (next) : (push @semi_primes,$p*$_) for @primes;
+ }
+ sort {$a<=>$b} @semi_primes;
+}
diff --git a/challenge-144/james-smith/perl/ch-2.pl b/challenge-144/james-smith/perl/ch-2.pl
index 024a36197b..a3a2b2590e 100644
--- a/challenge-144/james-smith/perl/ch-2.pl
+++ b/challenge-144/james-smith/perl/ch-2.pl
@@ -8,13 +8,53 @@ use Test::More;
use Benchmark qw(cmpthese timethis);
use Data::Dumper qw(Dumper);
-my (@seq,%seq_hash);
-
+say "@{[ ulam_expanded(1,2,1000) ]}";
+say "@{[ ulam_map(1,2,1000) ]}";
+say "@{[ ulam(1,2,1000) ]}";
+say "@{[ ulam_expanded(1,2,100) ]}";
+say "@{[ ulam_map(1,2,100) ]}";
say "@{[ ulam(1,2,100) ]}";
say "@{[ ulam(2,3,100) ]}";
say "@{[ ulam(2,5,100) ]}";
+cmpthese( 200, {
+ 'u' => sub { ulam(1,2,1000) },
+# 'm' => sub { ulam_map(1,2,1000) },
+ 'e' => sub { ulam_expanded(1,2,1000) },
+} );
+
sub ulam {
+ my%h=map{$_,$_}my@s=($_[0],my$n=$_[1]);
+ for(my$c=0;@s<$_[2];++$n,$c=0){
+ ($_>=$n/2)?(last):($h{$n-$_})&&$c++&&(last) for@s;
+ push@s,$h{$n}=$n if$c==1;
+ }
+ @s;
+}
+
+sub ulam_expanded {
+ my ($m, $n, $l) = @_;
+ my @seq = ($m,$n);
+ my %seq_hash = ( $m => 1, $n => 1 );
+ while( @seq < $l ) {
+ $n++;
+ my $count = 0;
+ foreach ( @seq ) {
+ last if $_ >= $n/2;
+ if( exists $seq_hash{ $n - $_ } ) {
+ $count++;
+ last if $count>1;
+ }
+ }
+ if( $count == 1 ) {
+ push @seq, $n;
+ $seq_hash{ $n } = 1;
+ }
+ }
+ return @seq;
+}
+
+sub ulam_map {
my%seq_hash=map{$_,$_}my@seq=($_[0],my$n=$_[1]);
for(;scalar @seq<$_[2];++$n){
push@seq,$seq_hash{$n}=$n if 1==grep{2*$_<$n&&$seq_hash{$n-$_}}@seq;