aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordcw <d.white@imperial.ac.uk>2022-06-12 22:43:27 +0100
committerdcw <d.white@imperial.ac.uk>2022-06-12 22:43:27 +0100
commit07adaccbe8b3a4274fb09b6fe61a7911ef23b7b4 (patch)
tree707e9de59f61ce8c154ddaa8f0a92ceabe96880a
parent13a1480fd1f537601db8884eb9b1f94775289f8e (diff)
downloadperlweeklychallenge-club-07adaccbe8b3a4274fb09b6fe61a7911ef23b7b4.tar.gz
perlweeklychallenge-club-07adaccbe8b3a4274fb09b6fe61a7911ef23b7b4.tar.bz2
perlweeklychallenge-club-07adaccbe8b3a4274fb09b6fe61a7911ef23b7b4.zip
imported my solutions to this week's tasks, both relatively easy
-rw-r--r--challenge-168/duncan-c-white/README62
-rw-r--r--challenge-168/duncan-c-white/perl/PrimeFactors.pm65
-rwxr-xr-xchallenge-168/duncan-c-white/perl/ch-1.pl47
-rwxr-xr-xchallenge-168/duncan-c-white/perl/ch-2.pl55
4 files changed, 194 insertions, 35 deletions
diff --git a/challenge-168/duncan-c-white/README b/challenge-168/duncan-c-white/README
index e34765e0f0..17fc15785c 100644
--- a/challenge-168/duncan-c-white/README
+++ b/challenge-168/duncan-c-white/README
@@ -1,51 +1,43 @@
-TASK 1: Circular Prime
+TASK 1: Perrin Prime
-Write a script to find out first 10 circular primes having at least 3
-digits (base 10).
+The Perrin sequence is defined to start with [3, 0, 2]; after that, term
+N is the sum of terms N-2 and N-3. (So it continues 3, 2, 5, 5, 7, ....)
-Please checkout https://en.wikipedia.org/wiki/Circular_prime for more information.
+A Perrin prime is a number in the Perrin sequence which is also a prime number.
-A circular prime is a prime number with the property that the number
-generated at each intermediate step when cyclically permuting its (base
-10) digits will also be prime.
+Calculate the first 13 Perrin Primes.
-Quote from the Wikipedia page:
+f(13) = [2, 3, 5, 7, 17, 29, 277, 367, 853, 14197, 43721, 1442968193, 792606555396977]
-"For example, 1193 is a circular prime, since 1931, 9311 and 3119 all
-are also prime.[3] A circular prime with at least two digits can only
-consist of combinations of the digits 1, 3, 7 or 9, because having 0, 2,
-4, 6 or 8 as the last digit makes the number divisible by 2, and having
-0 or 5 as the last digit makes it divisible by 5"
+MY NOTES: ok, sounds relatively easy, except that the 12th and 13th PP are
+enormous. I normally reusing my old favourite MakePrimes.pm (Sieve of
+Eratosthenes based) but this time I think I'll have to do it the old
+fashioned "try all factors up to sqrt()" approach.
-OUTPUT
-113, 197, 199, 337, 1193, 3779, 11939, 19937, 193939, 199933
+Task 2: Home Prime
+You are given an integer greater than 1.
-MY NOTES: ok, sounds relatively easy. The wikipedia page clarifies it.
-I'm reusing my old favourite MakePrimes.pm.
+Write a script to find the home prime of the given number.
-HOWEVER, my solution finds far more circular primes than the above output
-shows. If 113 is a CP (and it is cos 131 and 311 are also prime), then SO
-IS 131 AND SO IS 311, but the above list doesn't show it. Also, my solution
-computes ALL CPs with exactly N digits, rather than the first 10 with N or
-more digits.
+In number theory, the home prime HP(n) of an integer n greater than
+1 is the prime number obtained by repeatedly factoring the increasing
+concatenation of prime factors including repetitions.
+Further information can be found on Wikipedia
-Task 2: Task 2: Gamma Function
-
-Implement subroutine gamma() using the Lanczos approximation method.
-
-Ryan Thompson wrote an interesting blog explaining the subject in
-details. Highly recommended if you are looking for more information:
-https://ry.ca/2022/05/lanczos-approximation
+https://en.wikipedia.org/wiki/Home_prime
Example
-print gamma(3); # 1.99
-print gamma(5); # 24
-print gamma(7); # 719.99
+As given in the Wikipedia page:
+
+HP(10) = 773, as 10 factors as 2x5 yielding HP10(1) = 25, 25 factors
+as 5x5 yielding HP10(2) = HP25(1) = 55, 55 = 5x11 implies HP10(3)
+= HP25(2) = HP55(1) = 511, and 511 = 7x73 gives HP10(4) = HP25(3) =
+HP55(2) = HP511(1) = 773, a prime number.
-MY NOTES: Hell no. Complex numbers, ridiculously complicated formula,
-plus I've no idea what the Gamma function even is. This is far too
-mathematical for me, so I've no interest in doing it.
+MY NOTES: Ok, yet another prime variant. I'll have a go, but I note that
+the numbers get enormous, to the point where it's not even known if HP(49)
+can be calculated. Again can't use MakePrimes.pm..
diff --git a/challenge-168/duncan-c-white/perl/PrimeFactors.pm b/challenge-168/duncan-c-white/perl/PrimeFactors.pm
new file mode 100644
index 0000000000..5ec2210764
--- /dev/null
+++ b/challenge-168/duncan-c-white/perl/PrimeFactors.pm
@@ -0,0 +1,65 @@
+#
+# Prime factors:
+# compute the prime factors of a number, using the old fashioned
+# isprime "try all the factors"
+#
+
+use v5.10; # to get "say"
+use strict;
+use warnings;
+use Function::Parameters;
+#use Data::Dumper;
+
+
+my $debug = 0;
+
+
+#
+# my $isprime = isprime( $n );
+# Return 1 iff $n is a prime. Return 0 otherwise.
+#
+sub isprime
+{
+ my( $n ) = @_;
+ my $lim = int(sqrt($n));
+ foreach my $div (2..$lim)
+ {
+ return 0 if $n % $div == 0;
+ }
+ return 1;
+}
+
+
+#
+# my @factors = prime_factors( $n );
+# Break $n>1 apart into it's PRIME FACTORS (excluding 1).
+# Return the list of prime factors, smallest first.
+# eg. prime_factors( 228 ) = 2,2,3,19
+#
+fun prime_factors( $n )
+{
+ die "prime_factors: n ($n) must be >1\n" if $n<=1;
+ my @result;
+ my $lim = int(sqrt($n));
+ my $orign = $n;
+ foreach my $f (2..$lim)
+ {
+ next unless isprime($f);
+ say "pf($orign): considering prime factor $f" if $debug;
+ while( $n>1 && $n % $f == 0 )
+ {
+ say "pf($orign): n=$n, adding $f to result" if $debug;
+ push @result, $f;
+ my $other = $orign / $f;
+ push @result, $other if isprime($other) && $other != $f;
+ $n /= $f;
+ say "pf($orign): n /= $f (so n=$n now)" if $debug;
+ }
+ last if $n==1;
+ }
+ say "pf($orign): factors are @result";
+ return @result;
+}
+
+
+1;
diff --git a/challenge-168/duncan-c-white/perl/ch-1.pl b/challenge-168/duncan-c-white/perl/ch-1.pl
new file mode 100755
index 0000000000..d84a6e0d2f
--- /dev/null
+++ b/challenge-168/duncan-c-white/perl/ch-1.pl
@@ -0,0 +1,47 @@
+#!/usr/bin/perl
+#
+# TASK 1: Perrin Prime
+#
+# The Perrin sequence is defined to start with [3, 0, 2]; after that, term
+# N is the sum of terms N-2 and N-3. (So it continues 3, 2, 5, 5, 7, ....)
+#
+# A Perrin prime is a number in the Perrin sequence which is also a prime
+# number.
+#
+# Calculate the first 13 Perrin Primes.
+#
+# f(13) = [2, 3, 5, 7, 17, 29, 277, 367, 853, 14197, 43721, 1442968193, 792606555396977]
+#
+# MY NOTES: ok, sounds relatively easy, except that the 12th and 13th PP are
+# enormous. I normally reusing my old favourite MakePrimes.pm (Sieve of
+# Eratosthenes based) but this time I think I'll have to do it the old
+# fashioned "try all factors up to sqrt()" approach.
+#
+
+use strict;
+use warnings;
+use feature 'say';
+use Getopt::Long;
+#use Data::Dumper;
+
+use lib qw(.);
+use PrimeFactors;
+
+my $debug=0;
+die "Usage: perrin-prime [--debug] [N default 13]\n"
+ unless GetOptions( "debug"=>\$debug ) && @ARGV<2;
+my $n = shift // 13;
+
+my @perrin = qw(3 0 2);
+my %result = map { $_ => 1 } qw(2 3);
+
+while( keys %result < $n )
+{
+ # get next perrin number
+ my $np = $perrin[-2] + $perrin[-3];
+ push @perrin, $np;
+ say "next perrin no is $np" if $debug;
+ $result{$np}++ if isprime($np);
+}
+
+say "f($n) = [ ".join(',', sort { $a <=> $b } keys %result )." ]";
diff --git a/challenge-168/duncan-c-white/perl/ch-2.pl b/challenge-168/duncan-c-white/perl/ch-2.pl
new file mode 100755
index 0000000000..35ea3c4397
--- /dev/null
+++ b/challenge-168/duncan-c-white/perl/ch-2.pl
@@ -0,0 +1,55 @@
+#!/usr/bin/perl
+#
+# Task 2: Home Prime
+#
+# You are given an integer greater than 1.
+#
+# Write a script to find the home prime of the given number.
+#
+# In number theory, the home prime HP(n) of an integer n greater than
+# 1 is the prime number obtained by repeatedly factoring the increasing
+# concatenation of prime factors including repetitions.
+#
+# Further information can be found on Wikipedia
+#
+# https://en.wikipedia.org/wiki/Home_prime
+#
+# Example
+#
+# As given in the Wikipedia page:
+#
+# HP(10) = 773, as 10 factors as 2x5 yielding HP10(1) = 25, 25 factors
+# as 5x5 yielding HP10(2) = HP25(1) = 55, 55 = 5x11 implies HP10(3)
+# = HP25(2) = HP55(1) = 511, and 511 = 7x73 gives HP10(4) = HP25(3) =
+# HP55(2) = HP511(1) = 773, a prime number.
+#
+# MY NOTES: Ok, yet another prime variant. I'll have a go, but I note that
+# the numbers get enormous, to the point where it's not even known if HP(49)
+# can be calculated. Again can't use MakePrimes.pm, but can use a version
+# of PrimeFactors hacked to test for primeness directly.
+#
+
+use strict;
+use warnings;
+use feature 'say';
+use Getopt::Long;
+#use Data::Dumper;
+
+use lib qw(.);
+use PrimeFactors;
+
+my $debug=0;
+die "Usage: home-prime [--debug] [N default 10]\n"
+ unless GetOptions( "debug"=>\$debug ) && @ARGV<2;
+my $n = shift // 10;
+
+my $x = $n;
+do
+{
+ my @factors = prime_factors( $x );
+ say "debug: prime factors of $x are ". join(',',@factors) if $debug;
+ $x = join( '', @factors );
+ say "debug: next x = $x" if $debug;
+} while( ! isprime($x) );
+
+say "hp($n) = $x";