aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-144/wlmb/blog.txt1
-rwxr-xr-xchallenge-144/wlmb/perl/ch-1.pl23
-rwxr-xr-xchallenge-144/wlmb/perl/ch-2.pl27
3 files changed, 51 insertions, 0 deletions
diff --git a/challenge-144/wlmb/blog.txt b/challenge-144/wlmb/blog.txt
new file mode 100644
index 0000000000..76333f729a
--- /dev/null
+++ b/challenge-144/wlmb/blog.txt
@@ -0,0 +1 @@
+https://wlmb.github.io/2021/12/22/PWC144/
diff --git a/challenge-144/wlmb/perl/ch-1.pl b/challenge-144/wlmb/perl/ch-1.pl
new file mode 100755
index 0000000000..c5ce591b0d
--- /dev/null
+++ b/challenge-144/wlmb/perl/ch-1.pl
@@ -0,0 +1,23 @@
+#!/usr/bin/env perl
+# Perl weekly challenge 144
+# Task 1: Semiprime
+#
+# See https://wlmb.github.io/2021/12/22/PWC144/#task-1-semiprime
+use v5.12;
+use warnings;
+use PDL;
+use PDL::NiceSlice;
+my $N=shift//100; # get upper limit from command line
+my $sieve=ones($N+1); #Erastothenes sieve
+$sieve(0:1).=0; #0 and 1 are not primes
+$sieve($_**2:-1:$_).=0 for(2..sqrt($N)); #remove non-primes
+my $primes=$sieve->xvals->where($sieve);
+my $pairs=cat($primes, $primes(*))->mv(-1,0); # pairs of primes
+my $sp=$pairs->prodover; # semiprimes
+my ($p1, $p2, $semiprimes)=where($pairs((0)), $pairs((1)), $sp,
+ ($sp->xvals>=$sp->yvals)&($sp<100));
+my $indx=$semiprimes->qsorti; # order results
+my ($p1_o,$p2_o,$semiprimes_o)=map {$_->($indx)} ($p1, $p2, $semiprimes);
+say "The semiprimes not greater than $N are";
+say $semiprimes_o(($_)), "=", $p1_o(($_)), "*", $p2_o(($_))
+ foreach 0..$indx->nelem-1;
diff --git a/challenge-144/wlmb/perl/ch-2.pl b/challenge-144/wlmb/perl/ch-2.pl
new file mode 100755
index 0000000000..cb1e094603
--- /dev/null
+++ b/challenge-144/wlmb/perl/ch-2.pl
@@ -0,0 +1,27 @@
+#!/usr/bin/env perl
+# Perl weekly challenge 144
+# Task 2: Ulam Sequence
+#
+# See https://wlmb.github.io/2021/12/22/PWC144/#task-2-ulam-sequence
+use v5.12;
+use warnings;
+use PDL;
+use PDL::NiceSlice;
+say("Usage: ./ch-2.pl u v [N]\nto find the first N (default 10) terms".
+ " of the Ulam sequence u,v..."),exit unless @ARGV==2 || @ARGV==3;
+say("The given numbers should not be equal"), exit unless $ARGV[0]!=$ARGV[1];
+my $ulam=pdl(@ARGV[(0,1)]); # initialize sequence
+my $N=$ARGV[2]//10;
+foreach(3..$N){
+ my $sums=$ulam+$ulam->slice("*"); # addition table for Ulam sequence
+ my $ordered=$sums->where(
+ ($sums->xvals>$sums->yvals) # upper triangle in addition table
+ &($sums>$ulam((-1)) # remove previous terms
+ ))->qsort; # order
+ $ordered=$ordered->where( # eliminate duplicates with right or left
+ ($ordered!=$ordered->rotate(-1))
+ &($ordered!=$ordered->rotate(1))) if $ordered->nelem>1;
+ $ulam=$ulam->append($ordered((0)));
+}
+say "Input: u=$ARGV[0], v=$ARGV[1]", defined $ARGV[2]?", N=$N":"";
+say "Output: $ulam";