diff options
| author | dcw <d.white@imperial.ac.uk> | 2022-04-03 20:22:58 +0100 |
|---|---|---|
| committer | dcw <d.white@imperial.ac.uk> | 2022-04-03 20:22:58 +0100 |
| commit | be8ff67228ea6566aa907e3d2620b15e54ca8a01 (patch) | |
| tree | e2ac77322830e9b56d66bc7e543c78e3a49a58ba | |
| parent | ca99c2fbb53988ba726be364def605c27328dadc (diff) | |
| download | perlweeklychallenge-club-be8ff67228ea6566aa907e3d2620b15e54ca8a01.tar.gz perlweeklychallenge-club-be8ff67228ea6566aa907e3d2620b15e54ca8a01.tar.bz2 perlweeklychallenge-club-be8ff67228ea6566aa907e3d2620b15e54ca8a01.zip | |
imported my solutions to this week's challenge; 2 nice easy questions
| -rw-r--r-- | challenge-158/duncan-c-white/README | 73 | ||||
| -rw-r--r-- | challenge-158/duncan-c-white/perl/MakePrimes.pm | 97 | ||||
| -rwxr-xr-x | challenge-158/duncan-c-white/perl/ch-1.pl | 39 | ||||
| -rwxr-xr-x | challenge-158/duncan-c-white/perl/ch-2.pl | 46 |
4 files changed, 200 insertions, 55 deletions
diff --git a/challenge-158/duncan-c-white/README b/challenge-158/duncan-c-white/README index 424d544222..becee387dc 100644 --- a/challenge-158/duncan-c-white/README +++ b/challenge-158/duncan-c-white/README @@ -1,67 +1,30 @@ -TASK #1 - Pythagorean Means +TASK #1 - Additive Primes -You are given a set of integers. +Write a script to find out all Additive Primes <= 100. -Write a script to compute all three Pythagorean Means i.e Arithmetic Mean, -Geometric Mean and Harmonic Mean of the given set of integers. Please -refer to wikipedia page for more informations. +Additive primes are prime numbers for which the sum of their decimal +digits are also primes. -Example 1: +Output - Input: @n = (1,3,5,6,9) - Output: AM = 4.8, GM = 3.9, HM = 2.8 + 2, 3, 5, 7, 11, 23, 29, 41, 43, 47, 61, 67, 83, 89 -Example 2: +MY NOTES: ok. Pretty easy. Reuse my MakePrimes module, and code up +isprime(n) and isprime(sum_digits(n)) - Input: @n = (2,4,6,8,10) - Output: AM = 6.0, GM = 5.2, HM = 4.4 -Example 3: +TASK #2 - First Series Cuban Primes - Input: @n = (1,2,3,4,5) - Output: AM = 3.0, GM = 2.6, HM = 2.2 +Write a script to compute first series Cuban Primes <= 1000. Please +refer to https://en.wikipedia.org/wiki/Cuban_prime +for more information. -MY NOTES: ok. Pretty easy, although the geometric mean involves -calculating the product of the numbers, which may get pretty huge. -Tried bigrat, but it broke the nth-root calculation using **. +[That says: p = (y+1)**3 - y**3 for y>0, or p = 3y**2 + 3y + 1 for y>0] +Output -TASK #2 - Brazilian Number + 7, 19, 37, 61, 127, 271, 331, 397, 547, 631, 919. -You are given a number $n > 3. - -Write a script to find out if the given number is a Brazilian Number. - -A positive integer number N has at least one natural number B where -1 < B < N-1 where the representation of N in base B has same digits. - - -Example 1: - -Input: $n = 7 -Output: 1 - -Since 7 in base 2 is 111. - -Example 2: - -Input: $n = 6 -Output: 0 - -Since 6 in base 2 is 110, - 6 in base 3 is 20 and - 6 in base 4 is 12. - -Example 3: - -Input: $n = 8 -Output: 1 - -Since 8 in base 3 is 22. - - -MY NOTES: ok, so "same digits" really means "the same base-b digit -repeated throughout the entire string". Sounds pretty easy. -Added debugging mode to produce and display the "Since" messages, -formatted nicely. Then added tabulate mode to show the first N -Brazilian numbers (this interoperates nicely with -d). +MY NOTES: ok. Not quite clear from Wikipedia page whether 3y**2 + 3y + 1 +for all y>0 is prime, I assume that's not true, so that we have to check +isprime(3y**2 + 3y + 1) diff --git a/challenge-158/duncan-c-white/perl/MakePrimes.pm b/challenge-158/duncan-c-white/perl/MakePrimes.pm new file mode 100644 index 0000000000..6b5cd8e9fe --- /dev/null +++ b/challenge-158/duncan-c-white/perl/MakePrimes.pm @@ -0,0 +1,97 @@ +# +# mkprimes module (converted from mkprimes.c) +# + +use strict; +use warnings; +use Function::Parameters; + + +my $debug = 0; +my @foundprimes; # remember all primes we've found.. + + +fun prime_debug( $d ) +{ + $debug = $d; +} + + +# +# my @primes = primes_upto( $n ); +# Find all primes up to N; return a list of all such primes +# (note that 1 is not usually considered a prime) +# +fun primes_upto( $n ) +{ + my @isprime; + + for( my $i=1; $i<=$n; $i++ ) + { + $isprime[$i] = 1; # initially + } + + # now sieve the non-primes out.. + my $upper = int(sqrt($n)); + printf( "debug: n=%d, upper=%d\n", $n, $upper ) if $debug; + for( my $i=2; $i<=$upper; $i++ ) + { + if( $isprime[$i] ) + { + #printf( "debug: crossing out multiples of %d\n", $i ); + for( my $j=$i*$i; $j<=$n; $j+=$i ) + { + $isprime[$j] = 0; + } + } + } + + # after sieving, extract the primes + my @primes = grep { $isprime[$_] } 2..$n; + + # remember them + @foundprimes = @primes; + + return @primes; +} + + +# +# my @moreprimes = more_primes( $n, $m ); +# Need more primes! Have @foundprimes up to $n, but need +# to sieve primes from $n+1..$m, so re-sieve, return +# a list of all new primes (in the range $n+1..$m) that we find. +# +fun more_primes( $n, $m ) +{ + my %isprime; + + print "finding more primes from ", $n+1, "..$m\n" if $debug; + + for( my $i=$n+1; $i<=$m; $i++ ) + { + $isprime{$i} = 1; # pre-sieving + } + + # now sieve the non-primes out.. + foreach my $prime (@foundprimes) + { + # find first multiple of $prime > $n + my $mult = $prime * (int($n/$prime)+1); + + #print "debug: xo multiples of $prime from $mult to $m\n"; + + for( my $j=$mult; $j<=$m; $j+=$prime ) + { + delete $isprime{$j}; + } + } + + # after sieving, extract the primes + my @primes = grep { $isprime{$_} } $n+1..$m; + push @foundprimes, @primes; + return @primes; +} + + +1; diff --git a/challenge-158/duncan-c-white/perl/ch-1.pl b/challenge-158/duncan-c-white/perl/ch-1.pl new file mode 100755 index 0000000000..7e378d51d6 --- /dev/null +++ b/challenge-158/duncan-c-white/perl/ch-1.pl @@ -0,0 +1,39 @@ +#!/usr/bin/perl +# +# TASK #1 - Additive Primes +# +# Write a script to find out all Additive Primes <= 100. +# +# Additive primes are prime numbers for which the sum of their decimal +# digits are also primes. +# +# Output +# +# 2, 3, 5, 7, 11, 23, 29, 41, 43, 47, 61, 67, 83, 89 +# +# MY NOTES: ok. Pretty easy. Reuse my MakePrimes module, and code up +# isprime(n) and isprime(sum_digits(n)) +# + +use strict; +use warnings; +use feature 'say'; +use Getopt::Long; +use List::Util qw(sum0); +#use Data::Dumper; + +use lib qw(.); +use MakePrimes; + +my $debug=0; +die "Usage: additiive-primes [--debug] [limit] (default 100)\n" + unless GetOptions( "debug"=>\$debug ) && @ARGV<2; + +my $limit = shift // 100; + +my @primes = primes_upto( $limit ); +my %isprime = map { $_ => 1 } @primes; + +my @addprimes = grep { $isprime{ sum0( split(//,$_) ) } } @primes; + +say join(', ', @addprimes); diff --git a/challenge-158/duncan-c-white/perl/ch-2.pl b/challenge-158/duncan-c-white/perl/ch-2.pl new file mode 100755 index 0000000000..2b49eef7f6 --- /dev/null +++ b/challenge-158/duncan-c-white/perl/ch-2.pl @@ -0,0 +1,46 @@ +#!/usr/bin/perl +# +# TASK #2 - First Series Cuban Primes +# +# Write a script to compute first series Cuban Primes <= 1000. Please +# refer to https://en.wikipedia.org/wiki/Cuban_prime +# for more information. +# +# [That says: p = (y+1)**3 - y**3 for y>0, or p = 3y**2 + 3y + 1 for y>0] +# +# Output +# +# 7, 19, 37, 61, 127, 271, 331, 397, 547, 631, 919. +# +# MY NOTES: ok. Not quite clear from Wikipedia page whether 3y**2 + 3y + 1 +# for all y>0 is prime, I assume that's not true, so that we have to check +# isprime(3y**2 + 3y + 1) +# + +use strict; +use warnings; +use feature 'say'; +use Getopt::Long; +#use Data::Dumper; + +use lib qw(.); +use MakePrimes; + +my $debug=0; +die "Usage: first-cuban-primes [--debug] [limit] (default 1000)\n" + unless GetOptions( "debug"=>\$debug ) && @ARGV<2; + +my $limit = shift // 1000; + +my @primes = primes_upto( $limit ); +my %isprime = map { $_ => 1 } @primes; + +my @cuban1primes; +for( my $y=1; ; $y++ ) +{ + my $cubediff = 3 * $y * $y + 3 * $y + 1; + last if $cubediff > $limit; + push @cuban1primes, $cubediff if $isprime{$cubediff}; +} + +say join(', ', @cuban1primes); |
