diff options
| author | dcw <d.white@imperial.ac.uk> | 2022-06-12 22:43:27 +0100 |
|---|---|---|
| committer | dcw <d.white@imperial.ac.uk> | 2022-06-12 22:43:27 +0100 |
| commit | 07adaccbe8b3a4274fb09b6fe61a7911ef23b7b4 (patch) | |
| tree | 707e9de59f61ce8c154ddaa8f0a92ceabe96880a | |
| parent | 13a1480fd1f537601db8884eb9b1f94775289f8e (diff) | |
| download | perlweeklychallenge-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/README | 62 | ||||
| -rw-r--r-- | challenge-168/duncan-c-white/perl/PrimeFactors.pm | 65 | ||||
| -rwxr-xr-x | challenge-168/duncan-c-white/perl/ch-1.pl | 47 | ||||
| -rwxr-xr-x | challenge-168/duncan-c-white/perl/ch-2.pl | 55 |
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"; |
