aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrbaggy <js5@sanger.ac.uk>2022-01-12 15:59:26 +0000
committerdrbaggy <js5@sanger.ac.uk>2022-01-12 15:59:26 +0000
commitdd99d53e09a332c4ff5153b8bb54c9506a03860d (patch)
treee65264cbef15fbcd3e15dd12da74cc5084e507cb
parent94cdbab3f1198c78a3dcedb9ada1a8596114cfcb (diff)
parentd995c005f623c0f80f4cdfbf2247856c146fd7e3 (diff)
downloadperlweeklychallenge-club-dd99d53e09a332c4ff5153b8bb54c9506a03860d.tar.gz
perlweeklychallenge-club-dd99d53e09a332c4ff5153b8bb54c9506a03860d.tar.bz2
perlweeklychallenge-club-dd99d53e09a332c4ff5153b8bb54c9506a03860d.zip
Merge remote-tracking branch 'upstream/master'
-rwxr-xr-xchallenge-147/alexander-karelas/perl/ch-2.pl30
-rw-r--r--challenge-147/dave-jacoby/blog.txt1
-rw-r--r--challenge-147/dave-jacoby/perl/ch-1.pl35
-rw-r--r--challenge-147/dave-jacoby/perl/ch-2.pl35
-rwxr-xr-xchallenge-147/eric-cheung/excel-vba/Challenge_147.xlsmbin0 -> 25600 bytes
-rwxr-xr-xchallenge-147/eric-cheung/excel-vba/ch-1.bas86
-rwxr-xr-xchallenge-147/eric-cheung/python/ch-2.py45
-rw-r--r--challenge-147/luca-ferrari/blog-1.txt2
-rw-r--r--challenge-147/luca-ferrari/blog-2.txt2
-rw-r--r--challenge-147/luca-ferrari/blog-3.txt2
-rw-r--r--challenge-147/luca-ferrari/blog-4.txt2
-rw-r--r--challenge-147/luca-ferrari/blog-5.txt1
-rw-r--r--challenge-147/luca-ferrari/postgresql/ch-2.sql2
-rw-r--r--challenge-147/luca-ferrari/postgresql/ch-2b.sql46
-rwxr-xr-xchallenge-147/perlboy1967/perl/ch-1.pl40
-rwxr-xr-xchallenge-147/perlboy1967/perl/ch-2.pl56
-rw-r--r--challenge-147/peter-campbell-smith/blog.txt1
-rwxr-xr-xchallenge-147/peter-campbell-smith/perl/ch-1.pl70
-rwxr-xr-xchallenge-147/peter-campbell-smith/perl/ch-2.pl128
-rw-r--r--challenge-147/roger-bell-west/blog.txt1
-rw-r--r--challenge-147/ulrich-rieke/cpp/ch-1.cpp46
-rw-r--r--challenge-147/ulrich-rieke/haskell/ch-1.hs24
-rw-r--r--challenge-147/ulrich-rieke/perl/ch-2.pl42
-rw-r--r--challenge-147/ulrich-rieke/raku/ch-1.raku31
-rw-r--r--challenge-147/wlmb/blog.txt1
-rwxr-xr-xchallenge-147/wlmb/perl/ch-1.pl41
-rwxr-xr-xchallenge-147/wlmb/perl/ch-2.pl34
-rwxr-xr-xchallenge-147/wlmb/perl/ch-2a.pl41
-rwxr-xr-xchallenge-147/wlmb/perl/ch-2b.pl36
-rw-r--r--stats/pwc-current.json251
-rw-r--r--stats/pwc-language-breakdown-summary.json60
-rw-r--r--stats/pwc-language-breakdown.json2104
-rw-r--r--stats/pwc-leaders.json464
-rw-r--r--stats/pwc-summary-1-30.json118
-rw-r--r--stats/pwc-summary-121-150.json36
-rw-r--r--stats/pwc-summary-151-180.json110
-rw-r--r--stats/pwc-summary-181-210.json120
-rw-r--r--stats/pwc-summary-211-240.json116
-rw-r--r--stats/pwc-summary-241-270.json54
-rw-r--r--stats/pwc-summary-31-60.json108
-rw-r--r--stats/pwc-summary-61-90.json114
-rw-r--r--stats/pwc-summary-91-120.json104
-rw-r--r--stats/pwc-summary.json54
43 files changed, 2846 insertions, 1848 deletions
diff --git a/challenge-147/alexander-karelas/perl/ch-2.pl b/challenge-147/alexander-karelas/perl/ch-2.pl
new file mode 100755
index 0000000000..b6548da74a
--- /dev/null
+++ b/challenge-147/alexander-karelas/perl/ch-2.pl
@@ -0,0 +1,30 @@
+#!/usr/bin/env perl
+
+use v5.32;
+use warnings;
+
+use experimental 'signatures';
+
+my @cache;
+my %cache;
+sub get_nth_pentagon_number ($n) {
+ my $pentagon = $cache[$n];
+ $pentagon //= do {
+ $cache[$n] = $n * (3 * $n - 1) / 2;
+ $cache{ $cache[$n] } = $n;
+ }
+}
+
+for (my $i = 1; ; $i++) {
+ my $ith = get_nth_pentagon_number($i);
+ get_nth_pentagon_number(2 * $i - 1);
+ get_nth_pentagon_number(2 * $i);
+ for (my $j = 1; $j < $i; $j++) {
+ my $jth = get_nth_pentagon_number($j);
+ if (exists $cache{$ith + $jth} and exists $cache{$ith - $jth}) {
+ say "P($i) + P($j) = $ith + $jth = @{[ $ith + $jth ]} = P(", $cache{$ith + $jth}, ")";
+ say "P($i) - P($j) = $ith - $jth = @{[ $ith - $jth ]} = P(", $cache{$ith - $jth}, ")";
+ exit;
+ }
+ }
+}
diff --git a/challenge-147/dave-jacoby/blog.txt b/challenge-147/dave-jacoby/blog.txt
new file mode 100644
index 0000000000..e386698c3c
--- /dev/null
+++ b/challenge-147/dave-jacoby/blog.txt
@@ -0,0 +1 @@
+https://jacoby.github.io/2022/01/11/truncations-and-pentagons-the-weekly-challenge-147.html \ No newline at end of file
diff --git a/challenge-147/dave-jacoby/perl/ch-1.pl b/challenge-147/dave-jacoby/perl/ch-1.pl
new file mode 100644
index 0000000000..197c72f5b7
--- /dev/null
+++ b/challenge-147/dave-jacoby/perl/ch-1.pl
@@ -0,0 +1,35 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use feature qw{ say postderef signatures state };
+no warnings qw{ experimental };
+
+my %primes;
+my %trunc;
+my $c = 1;
+my $n = 2;
+
+while (1) {
+ if ( $n !~ /0/mx && is_prime($n) ) {
+ $primes{$n}++;
+ my $copy = $n;
+ while ( length $copy > 0 ) {
+ last unless $primes{$copy};
+ substr( $copy, 0, 1 ) = '';
+ if ( $copy eq '' ) {
+ $trunc{$n}++ if $copy eq '';
+ last;
+ }
+ }
+ last if scalar keys %trunc > 30;
+ }
+ $n++;
+}
+
+say join ', ', sort { $a <=> $b } keys %trunc;
+
+sub is_prime ($n) {
+ for ( 2 .. sqrt $n ) { return unless $n % $_ }
+ return 1;
+}
diff --git a/challenge-147/dave-jacoby/perl/ch-2.pl b/challenge-147/dave-jacoby/perl/ch-2.pl
new file mode 100644
index 0000000000..61f3b1b1d6
--- /dev/null
+++ b/challenge-147/dave-jacoby/perl/ch-2.pl
@@ -0,0 +1,35 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use feature qw{ say postderef signatures state };
+no warnings qw{ experimental };
+
+my $top = 10_000;
+my @pentagon = map { pentagon($_) } 0 .. $top;
+my %pentagon = map { $_ => 1 } @pentagon;
+delete $pentagon{0};
+
+for my $i ( 1 .. $top ) {
+ for my $j ( 1 .. $i ) {
+ my $pi = $pentagon[$i];
+ my $pj = $pentagon[$j];
+ my $sum = $pi + $pj;
+ if ( $pentagon{$sum} ) {
+ my $product = abs( $pi - $pj );
+ if ( $pentagon{$product} ) {
+ say <<"END";
+ P($i) = $pi
+ P($j) = $pj
+ $pi + $pj = $sum
+ abs( $pi - $pj ) = $product
+END
+ exit;
+ }
+ }
+ }
+}
+
+sub pentagon ( $n ) {
+ return $n * ( ( $n * 3 ) - 1 ) / 2;
+}
diff --git a/challenge-147/eric-cheung/excel-vba/Challenge_147.xlsm b/challenge-147/eric-cheung/excel-vba/Challenge_147.xlsm
new file mode 100755
index 0000000000..6f7427aff8
--- /dev/null
+++ b/challenge-147/eric-cheung/excel-vba/Challenge_147.xlsm
Binary files differ
diff --git a/challenge-147/eric-cheung/excel-vba/ch-1.bas b/challenge-147/eric-cheung/excel-vba/ch-1.bas
new file mode 100755
index 0000000000..558dd6656c
--- /dev/null
+++ b/challenge-147/eric-cheung/excel-vba/ch-1.bas
@@ -0,0 +1,86 @@
+Attribute VB_Name = "ModTask_01"
+Option Explicit
+
+Public Const strMyTitle As String = "Eric Cheung"
+
+Option Base 1
+Public nPrimeArr() As Long
+Public nPrimeCnt As Integer
+
+Function IsPrime(nInput As Integer) As Boolean
+
+ Dim nNumLoop As Integer
+
+ If nInput = 1 Then
+ IsPrime = False
+ Exit Function
+ End If
+
+ For nNumLoop = LBound(nPrimeArr) To UBound(nPrimeArr)
+ If nInput = nPrimeArr(nNumLoop) Then
+ IsPrime = True
+ Exit Function
+ ElseIf nInput Mod nPrimeArr(nNumLoop) = 0 Then
+ IsPrime = False
+ Exit Function
+ End If
+ Next nNumLoop
+
+ IsPrime = True
+
+End Function
+
+Function IsTruncatablePrime(nInput As Integer) As Boolean
+
+ If nInput = 0 Then
+ IsTruncatablePrime = False
+ Exit Function
+ ElseIf Not IsPrime(nInput) Then
+ IsTruncatablePrime = False
+ Exit Function
+ End If
+
+ nPrimeCnt = nPrimeCnt + 1
+ ReDim Preserve nPrimeArr(1 To nPrimeCnt)
+ nPrimeArr(nPrimeCnt) = nInput
+
+ If nInput < 10 Then
+ IsTruncatablePrime = True
+ Else
+ If Val(Mid(CStr(nInput), 2, 1)) = 0 Then
+ IsTruncatablePrime = False
+ Exit Function
+ End If
+ IsTruncatablePrime = IsTruncatablePrime(Val(Right(CStr(nInput), Len(CStr(nInput)) - 1)))
+ End If
+
+End Function
+
+Sub Task_01()
+
+ Const nTruncatablePrimeCntMax As Integer = 20
+
+ Dim nLoop As Integer, nTruncatablePrimeCnt As Integer
+ Dim strMsg As String
+
+ ReDim nPrimeArr(1 To 1)
+
+ nPrimeCnt = 1
+ nPrimeArr(1) = 2
+ nLoop = 3
+
+ nTruncatablePrimeCnt = 1
+
+ strMsg = "First " & nTruncatablePrimeCntMax & " left-truncatable prime numbers in base 10 are: " & 2
+
+ Do While (nTruncatablePrimeCnt < nTruncatablePrimeCntMax)
+ If IsTruncatablePrime(nLoop) Then
+ strMsg = strMsg & ", " & nLoop
+ nTruncatablePrimeCnt = nTruncatablePrimeCnt + 1
+ End If
+ nLoop = nLoop + 1
+ Loop
+
+ MsgBox strMsg, vbOKOnly, strMyTitle
+
+End Sub
diff --git a/challenge-147/eric-cheung/python/ch-2.py b/challenge-147/eric-cheung/python/ch-2.py
new file mode 100755
index 0000000000..6a716b2ddd
--- /dev/null
+++ b/challenge-147/eric-cheung/python/ch-2.py
@@ -0,0 +1,45 @@
+## Remarks
+## https://www.mathblog.dk/project-euler-44-smallest-pair-pentagonal-numbers/
+## https://radiusofcircle.blogspot.com/2016/06/problem-44-project-euler-solution-with-python.html
+## http://radiusofcircle.blogspot.com
+
+## Time Module for Calculating Execution Time
+import time
+
+## Time At The Start of Program Execution
+dStartTime = time.time()
+
+def is_pentagonal(nInput):
+ ## Function To Check If The Number is Pentagonal Number or Not
+ if (1 + (24 * nInput + 1) ** 0.5) % 6 == 0:
+ return True
+ return False
+
+## Flag To Check If The Number Is Found Or Not
+bFlag = True
+
+# While Loop Iterator
+nLoop = 1
+
+# While Loop
+while bFlag:
+ nNum_01 = nLoop * (3 * nLoop - 1) / 2
+ for nSubLoop in range(1, nLoop):
+ nNum_02 = nSubLoop * (3 * nSubLoop - 1) / 2
+ if is_pentagonal(nNum_01 + nNum_02) and is_pentagonal(nNum_01 - nNum_02):
+ print ("nLoop = " + str(nLoop) + ", nSubLoop = " + str(nSubLoop))
+ bFlag = False
+ break
+ nLoop = nLoop + 1
+
+# Time At The End of Program Execution
+dEndTime = time.time()
+
+# Printing The Total Time For Execution
+print ("Time Needed: " + str(dEndTime - dStartTime))
+
+
+## Result
+## nLoop = 2167, nSubLoop = 1020
+## Time Needed: 1.1174473762512207
+
diff --git a/challenge-147/luca-ferrari/blog-1.txt b/challenge-147/luca-ferrari/blog-1.txt
index af17183edb..f5a4859575 100644
--- a/challenge-147/luca-ferrari/blog-1.txt
+++ b/challenge-147/luca-ferrari/blog-1.txt
@@ -1 +1 @@
-https://fluca1978.github.io/2022/01/04/PerlWeeklyChallenge146.html#task1
+https://fluca1978.github.io/2022/01/10/PerlWeeklyChallenge147.html#task1
diff --git a/challenge-147/luca-ferrari/blog-2.txt b/challenge-147/luca-ferrari/blog-2.txt
index 5e5d379514..c3a26988bb 100644
--- a/challenge-147/luca-ferrari/blog-2.txt
+++ b/challenge-147/luca-ferrari/blog-2.txt
@@ -1 +1 @@
-https://fluca1978.github.io/2022/01/04/PerlWeeklyChallenge146.html#task2
+https://fluca1978.github.io/2022/01/10/PerlWeeklyChallenge147.html#task2
diff --git a/challenge-147/luca-ferrari/blog-3.txt b/challenge-147/luca-ferrari/blog-3.txt
index aa716b41b9..1854457738 100644
--- a/challenge-147/luca-ferrari/blog-3.txt
+++ b/challenge-147/luca-ferrari/blog-3.txt
@@ -1 +1 @@
-https://fluca1978.github.io/2022/01/04/PerlWeeklyChallenge146.html#task1pg
+https://fluca1978.github.io/2022/01/10/PerlWeeklyChallenge146.html#task1pg
diff --git a/challenge-147/luca-ferrari/blog-4.txt b/challenge-147/luca-ferrari/blog-4.txt
index 520b859582..63d8983e4e 100644
--- a/challenge-147/luca-ferrari/blog-4.txt
+++ b/challenge-147/luca-ferrari/blog-4.txt
@@ -1 +1 @@
-https://fluca1978.github.io/2022/01/04/PerlWeeklyChallenge146.html#task2pg
+https://fluca1978.github.io/2022/01/10/PerlWeeklyChallenge147.html#task2pg
diff --git a/challenge-147/luca-ferrari/blog-5.txt b/challenge-147/luca-ferrari/blog-5.txt
new file mode 100644
index 0000000000..b872164f21
--- /dev/null
+++ b/challenge-147/luca-ferrari/blog-5.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2022/01/10/PerlWeeklyChallenge147.html#task2pgb
diff --git a/challenge-147/luca-ferrari/postgresql/ch-2.sql b/challenge-147/luca-ferrari/postgresql/ch-2.sql
index 61465a21c6..67ed7cdeb3 100644
--- a/challenge-147/luca-ferrari/postgresql/ch-2.sql
+++ b/challenge-147/luca-ferrari/postgresql/ch-2.sql
@@ -66,8 +66,6 @@ BEGIN
IF FOUND THEN
SELECT current_tuple.n
, other_tuple.n
- , current_tuple.p
- , other_tuple.p
, current_tuple.p + other_tuple.p
, abs( current_tuple.p - other_tuple.p )
, p1.n
diff --git a/challenge-147/luca-ferrari/postgresql/ch-2b.sql b/challenge-147/luca-ferrari/postgresql/ch-2b.sql
new file mode 100644
index 0000000000..427419b900
--- /dev/null
+++ b/challenge-147/luca-ferrari/postgresql/ch-2b.sql
@@ -0,0 +1,46 @@
+CREATE OR REPLACE FUNCTION
+f_pentagon( n bigint )
+RETURNS bigint
+AS
+$CODE$
+ SELECT ( n * ( 3 * n - 1 ) / 2 );
+$CODE$
+LANGUAGE sql
+IMMUTABLE;
+
+/*
+pentagon_pairs
+----------------
+1020, 2167
+2167, 1020
+(2 rows)
+
+Time: 5820,066 ms (00:05,820)
+
+*/
+WITH RECURSIVE pentagons( n, p )
+AS
+(
+ SELECT 1 AS n
+ , f_pentagon( 1 ) AS p
+
+UNION
+ SELECT p.n + 1
+ , f_pentagon( p.n + 1 )
+ FROM pentagons p
+ WHERE p.n < 5000
+)
+
+SELECT format( '%s, %s', l.n, r.n ) AS pentagon_pairs
+FROM pentagons l, pentagons r
+WHERE EXISTS(
+ SELECT *
+ FROM pentagons ps
+ WHERE ps.p = l.p + r.p
+ )
+AND EXISTS (
+ SELECT *
+ FROM pentagons ps
+ WHERE ps.p = abs( l.p - r.p )
+ )
+;
diff --git a/challenge-147/perlboy1967/perl/ch-1.pl b/challenge-147/perlboy1967/perl/ch-1.pl
new file mode 100755
index 0000000000..2fbd74581f
--- /dev/null
+++ b/challenge-147/perlboy1967/perl/ch-1.pl
@@ -0,0 +1,40 @@
+#!/bin/perl
+
+=pod
+
+The Weekly Challenge - 147
+ - https://perlweeklychallenge.org/blog/perl-weekly-challenge-147/#TASK1
+
+Author: Niels 'PerlBoy' van Dijke
+
+TASK #1 › Truncatable Prime
+Submitted by: Mohammad S Anwar
+
+Write a script to generate first 20 left-truncatable prime numbers in base 10.
+
+ || In number theory, a left-truncatable prime is a prime number which, in a
+ || given base, contains no 0, and if the leading left digit is successively
+ || removed, then all resulting numbers are primes.
+
+=cut
+
+use v5.16;
+
+use Math::Primality qw(next_prime);
+
+my @tPrimes;
+my %primes;
+
+my $n = 1;
+do {
+ $n = next_prime($n);
+ $primes{$n}++;
+
+ if (index($n,0)<0) {
+ my $p = $n;
+ 1 while ($p =~ s#^.## && exists $primes{$p});
+ push(@tPrimes,$n) if ($p eq '');
+ }
+} while (scalar @tPrimes < 20);
+
+printf "%s\n", join(',',@tPrimes);
diff --git a/challenge-147/perlboy1967/perl/ch-2.pl b/challenge-147/perlboy1967/perl/ch-2.pl
new file mode 100755
index 0000000000..9a96d111c4
--- /dev/null
+++ b/challenge-147/perlboy1967/perl/ch-2.pl
@@ -0,0 +1,56 @@
+#!/bin/perl
+
+=pod
+
+The Weekly Challenge - 147
+ - https://perlweeklychallenge.org/blog/perl-weekly-challenge-147/#TASK2
+
+Author: Niels 'PerlBoy' van Dijke
+
+TASK #2 › Pentagon Numbers
+Submitted by: Mohammad S Anwar
+
+Write a sript to find the first pair of Pentagon Numbers whose sum and difference
+are also a Pentagon Number.
+
+ || Pentagon numbers can be defined as P(n) = n(3n - 1)/2.
+
+
+=cut
+
+use v5.16;
+
+sub pentagonNumber($) {
+ $_[0]*(3*$_[0]-1) >> 1;
+}
+
+my @p = (undef);
+my %pIdx;
+
+my $i = 1;
+
+while (1) {
+ push(@p,pentagonNumber scalar @p);
+ $pIdx{$p[-1]} = scalar @p - 1;
+
+ foreach my $j (1 .. $i-1) {
+ my $dif = $p[$i] - $p[$j];
+ next if !exists $pIdx{$dif};
+
+ my $sum = $p[$i] + $p[$j];
+
+ while ($p[-1] <= $sum) {
+ push(@p,pentagonNumber scalar @p);
+ $pIdx{$p[-1]} = scalar @p - 1;
+ }
+
+ if (exists $pIdx{$sum}) {
+ printf "P(%d) + P(%d) = %d + %d = %d = P(%d)\n",
+ $i, $j, $p[$i], $p[$j], $sum, $pIdx{$sum};
+ printf "P(%d) - P(%d) = %d - %d = %d = P(%d)\n",
+ $i, $j, $p[$i], $p[$j], $dif, $pIdx{$dif};
+ exit;
+ }
+ }
+ $i++;
+}
diff --git a/challenge-147/peter-campbell-smith/blog.txt b/challenge-147/peter-campbell-smith/blog.txt
new file mode 100644
index 0000000000..78e76441f9
--- /dev/null
+++ b/challenge-147/peter-campbell-smith/blog.txt
@@ -0,0 +1 @@
+https://pjcs-pwc.blogspot.com/2022/01/chop-off-their-heads-and-conquer.html
diff --git a/challenge-147/peter-campbell-smith/perl/ch-1.pl b/challenge-147/peter-campbell-smith/perl/ch-1.pl
new file mode 100755
index 0000000000..0a3901fe78
--- /dev/null
+++ b/challenge-147/peter-campbell-smith/perl/ch-1.pl
@@ -0,0 +1,70 @@
+#!/usr/bin/perl
+
+# Peter Campbell Smith - 2022-01-10
+# PWC 147 task 1
+
+use v5.28;
+use warnings;
+use strict;
+
+# Write a script to generate first 20 left-truncatable prime numbers in base 10.
+# In number theory, a left-truncatable prime is a prime number which, in a given base,
+# contains no 0, and if the leading left digit is successively removed, then all
+# resulting numbers are primes.
+
+# Note that the last digit cannot be 2, 4, 5, 6, 8, 0 as no primes end with those
+# and cannot be 9 as when all the preceding digits are removed, 9 is not prime,
+# so the last digit can only be 1, 3 or 7.
+
+# The definition above speaks of 'all resulting numbers' so I am ruling out
+# single-digit prime numbers as they have no 'resulting numbers' when the
+# leftmost digit is removed.
+
+my ($seeking, $prime_index, $from, $to, $test, $this, @not_a_prime, $string, $count,
+ $start, $factor, $multiple, $secs);
+
+# initialise
+$seeking = 20; # how many to find
+$count = 0; # how many found
+
+# find primes in ranges of 1000
+$secs = time;
+for ($from = 1; ; $from += 1000) {
+ $to = $from + 999;
+
+ # loop over all the possible factors, ie primes < sqrt($to)
+ for $factor (2 .. int(sqrt($to))) {
+ next if defined $not_a_prime[$factor]; # already known as not a prime
+
+ # mark all the multiples of $factor as non-primes (sieve of Eratosthenes)
+ $start = int($from / $factor); # multiples less than $start have already been done
+ $start = 2 if $start < 2;
+ for ($multiple = $start; $factor * $multiple <= $to; $multiple ++) {
+ $not_a_prime[$factor * $multiple] = 1;
+ }
+ }
+
+ # now test the primes in this range for left-truncatability
+ TEST: for $test ($from .. $to) {
+
+ # remove ineligibles - not prime, is a single digit, contains 0 or ends in 9
+ next if (defined $not_a_prime[$test] or $test =~ m|0| or $test =~ m|9$| or $test < 11);
+
+ # test for left-truncatability and construct string showing proof
+ $this = $test;
+ $string = qq[$this];
+
+ # remove successive left digits and test the residue for primeness
+ while ($this =~ s|\d(\d+)|$1|) {
+ next TEST if $not_a_prime[$this];
+ $string .= qq[ > $this];
+ }
+
+ # an answer!
+ say $string;
+ if (++ $count >= $seeking) {
+ say '' . (time - $secs) . qq[ seconds\n];
+ exit;
+ }
+ }
+}
diff --git a/challenge-147/peter-campbell-smith/perl/ch-2.pl b/challenge-147/peter-campbell-smith/perl/ch-2.pl
new file mode 100755
index 0000000000..e10b24053a
--- /dev/null
+++ b/challenge-147/peter-campbell-smith/perl/ch-2.pl
@@ -0,0 +1,128 @@
+#!/usr/bin/perl
+
+# Peter Campbell Smith - 2022-01-10
+# PWC 147 task 2
+
+use v5.28;
+use warnings;
+use strict;
+
+# Write a script to find the first pair of Pentagon Numbers whose sum and difference
+# are also a Pentagon Number. Pentagon numbers can be defined as P(n) = n(3n - 1)/2.
+
+my $seeking = 1;
+# first_method(); # see blog - it works but is slow
+second_method(); # this is better
+
+#---
+
+sub first_method {
+
+ # first method
+ my ($found, $n, $pentagon, %p, @f, $m, $diff, %queue, $sum, $mm, $nn, $sum2, $start);
+
+ $start = time;
+ $found = 0;
+
+ for ($n = 1; ; $n ++) {
+
+ # generate pentagon numbers sequentially
+ $pentagon = $n * (3 * $n - 1) / 2;
+ $p{$pentagon} = $n; # so for any $j <= $n, $j is a pentagon number if $p{$j}
+ $f[$n] = $pentagon; # and the $jth pentagon number is $f[$j]
+ next if $n == 1;
+
+ # check the difference between this pentagon number ($n) and all smaller ones ($m)
+ for $m (1 .. $n - 1) {
+ $diff = $pentagon - $f[$m];
+ next unless $p{$diff}; # difference is not a pentagon number
+
+ # the difference is pentagonal; the sum will be more than $pentagon so put it in a queue to be checked later
+ $queue{sprintf('%012d', $f[$m] + $pentagon)} = [$m, $n]; # zero padded key so they sort numerically
+
+ # test per wikipedia
+ $sum = $f[$m] + $pentagon;
+ }
+
+ # is $pentagon in the queue of possible answers?
+ for $sum (sort keys %queue) {
+ ($mm, $nn) = @{$queue{$sum}};
+
+ # this queued number is the sum of 2 pentagons which differ by a pentagon, so ... an answer!
+ if ($sum == $pentagon) { # the queued sum is the pentagon we've just found
+ $diff = $f[$nn] - $f[$mm];
+ $sum2 = $sum + 0; # get rid of zero padding
+ say qq[First method: ];
+ say qq[Pentagon no $mm is $f[$mm]];
+ say qq[Pentagon no $nn is $f[$nn]];
+ say qq[Their sum is $sum2 which is pentagon number $n];
+ say qq[Their difference is $diff which is pentagon number $p{$diff}];
+
+ if (++ $found == $seeking) { # we've achieved the goal
+ say '' . (time - $start) . qq[ seconds\n];
+ return;
+ }
+ delete $queue{$sum};
+
+ # this queued sum of 2 pentagon numbers is less than the one we just found,
+ # so it isn't a pentagon number, so take it out of the queue
+ } elsif ($sum < $pentagon) {
+ delete $queue{$sum};
+
+ # else it's still larger than the pentagon we just found, so leave it in the queue
+ } else {
+ last; # and any others are larger still so we con;t need to look at them yet
+ }
+ }
+ }
+}
+
+sub second_method {
+
+ my ($found, $n, $i, $s, $m, $diff, $sum, %p, @f, $start);
+
+ $found = 0;
+ $start = time;
+
+ for ($n = 1; ; $n ++) {
+
+ # find pentagon numbers sequentially
+ next unless ($i = is_pentagonal($n)); # so $n is the $i'th pentagon
+
+ # so $n is pentagonal
+ $f[$i] = $n; # and the $i'th pentagon number is $f[$i]
+ $p{$n} = $i; # if n is a pentagon, it is the $p{$n}'th one
+ next if $n == 1;
+
+ # check the difference and sum of this pentagon number ($n) and all smaller ones ($m)
+ for $m (1 .. $i - 1) {
+ $diff = $n - $f[$m];
+ $sum = $n + $f[$m];
+
+ # difference is not a pentagon number
+ next unless $p{$diff};
+ next unless $s = is_pentagonal($sum); # sum is not a pentagon number
+
+ # result!
+ say qq[Second method: ];
+ say qq[Pentagon no $i is $n];
+ say qq[Pentagon no $m is $f[$m]];
+ say qq[Their sum is $sum which is pentagon number $s];
+ say qq[Their difference is $diff which is pentagon number $p{$diff}];
+ if (++ $found == $seeking) {
+ say '' . (time - $start) . qq[ secs\n];
+ return;
+ }
+ }
+ }
+}
+
+sub is_pentagonal {
+
+ # per Wikipedia
+
+ my $test = (sqrt(24 * $_[0] + 1) + 1) / 6;
+ my $test1 = $test - int($test + 1e-19);
+ return (abs($test1) <= 1e-19) ? $test : 0;
+}
+
diff --git a/challenge-147/roger-bell-west/blog.txt b/challenge-147/roger-bell-west/blog.txt
new file mode 100644
index 0000000000..bd7837be26
--- /dev/null
+++ b/challenge-147/roger-bell-west/blog.txt
@@ -0,0 +1 @@
+https://blog.firedrake.org/archive/2022/01/The_Weekly_Challenge_147__Truncating_the_Pentagon.html
diff --git a/challenge-147/ulrich-rieke/cpp/ch-1.cpp b/challenge-147/ulrich-rieke/cpp/ch-1.cpp
new file mode 100644
index 0000000000..975ba98215
--- /dev/null
+++ b/challenge-147/ulrich-rieke/cpp/ch-1.cpp
@@ -0,0 +1,46 @@