diff options
| -rw-r--r-- | challenge-158/athanasius/perl/ch-1.pl | 106 | ||||
| -rw-r--r-- | challenge-158/athanasius/perl/ch-2.pl | 129 | ||||
| -rw-r--r-- | challenge-158/athanasius/raku/ch-1.raku | 107 | ||||
| -rw-r--r-- | challenge-158/athanasius/raku/ch-2.raku | 100 |
4 files changed, 442 insertions, 0 deletions
diff --git a/challenge-158/athanasius/perl/ch-1.pl b/challenge-158/athanasius/perl/ch-1.pl new file mode 100644 index 0000000000..bbf06525e3 --- /dev/null +++ b/challenge-158/athanasius/perl/ch-1.pl @@ -0,0 +1,106 @@ +#!perl + +############################################################################### +=comment + +Perl Weekly Challenge 158 +========================= + +TASK #1 +------- +*Additive Primes* + +Submitted by: Mohammad S Anwar + +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 + +=cut +############################################################################### + +#--------------------------------------# +# Copyright © 2022 PerlMonk Athanasius # +#--------------------------------------# + +#============================================================================== +=comment + +Algorithm +--------- +1. Generate primes in the required range using the Sieve of Eratosthenes [3] +2. For each prime in the sieve: + - sum the digits + - if the sum is a prime number recorded in the sieve, add it to the list of + additive primes +3. Output the list of additive primes + +References +---------- +[1] "A046704 Additive primes: sum of digits is a prime.", OEIS, + https://oeis.org/A046704 +[2] Reinhard Zumkeller, "Table of n, a(n) for n = 1..10000", OEIS, + https://oeis.org/A046704/b046704.txt +[3] "Sieve of Eratosthenes", Wikipedia, + https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes + +=cut +#============================================================================== + +use strict; +use warnings; +use Const::Fast; + +const my $MAX => 100; +const my $USAGE => "Usage:\n perl $0\n"; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + $| = 1; + print "\nChallenge 158, Task #1: Additive Primes (Perl)\n\n"; +} + +#============================================================================== +MAIN: +#============================================================================== +{ + my $args = scalar @ARGV; + $args == 0 or die 'ERROR: Expected 0 command line arguments, found ' . + "$args\n$USAGE"; + + my @is_prime = (0, 0, (1) x ($MAX - 1)); # Sieve: 0, 1, (2 .. $MAX) + + for my $n (0 .. $MAX) # Find the primes + { + next unless $is_prime[ $n ]; # Skip non-primes + + for (my $i = 2 * $n; $i <= $MAX; $i += $n) + { + $is_prime[ $i ] = 0; + } + } + + my @additive_primes; + + for my $p (0 .. $MAX) + { + next unless $is_prime[ $p ]; # Skip non-primes + + my $sum = 0; + $sum += $_ for split '', $p; + + push @additive_primes, $p if $is_prime[ $sum ]; + } + + printf "Additive primes <= %d:\n\n %s\n", + $MAX, join ', ', @additive_primes; +} + +############################################################################### diff --git a/challenge-158/athanasius/perl/ch-2.pl b/challenge-158/athanasius/perl/ch-2.pl new file mode 100644 index 0000000000..72873e91bf --- /dev/null +++ b/challenge-158/athanasius/perl/ch-2.pl @@ -0,0 +1,129 @@ +#!perl + +############################################################################### +=comment + +Perl Weekly Challenge 158 +========================= + +TASK #2 +------- +*First Series Cuban Primes* + +Submitted by: Mohammad S Anwar + +Write a script to compute first series Cuban Primes <= 1000. Please refer +[ https://en.wikipedia.org/wiki/Cuban_prime |wikipedia page] for more informa- +tions. + +Output + + 7, 19, 37, 61, 127, 271, 331, 397, 547, 631, 919. + +=cut +############################################################################### + +#--------------------------------------# +# Copyright © 2022 PerlMonk Athanasius # +#--------------------------------------# + +#============================================================================== +=comment + +Algorithm +--------- +The first-series Cuban Primes are a subset of the centred hexagonal (or "hex") +numbers [1, 3]. So, the algorithm begins by generating consecutive hex numbers, +using the formula: + + H(n) = 3n² - 3n + 1 + +where H(n) is the nth centered hexagonal number [2]. + +As each hex number is generated, it is tested for primality using the Sieve of +Eratosthenes (which is created on first call for integers in the target range). +Hex numbers found to be prime are stored. + +When all hex numbers in the target range have been evaluated, the stored prime +hex numbers are output as the required first-series Cuban Primes. + +References +---------- +[1] "A002407 Cuban primes: primes which are the difference of two consecutive + cubes.", OEIS, https://oeis.org/A002407 +[2] "Centered hexagonal number", Wikipedia, + https://en.wikipedia.org/wiki/Centered_hexagonal_number +[3] "Cuban prime", Wikipedia, https://en.wikipedia.org/wiki/Cuban_prime + +=cut +#============================================================================== + +use strict; +use warnings; +use feature qw( state ); +use Const::Fast; + +const my $MAX => 1_000; +const my $USAGE => "Usage:\n perl $0\n"; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + $| = 1; + print "\nChallenge 158, Task #2: First Series Cuban Primes (Perl)\n\n"; +} + +#============================================================================== +MAIN: +#============================================================================== +{ + my $args = scalar @ARGV; + $args == 0 or die 'ERROR: Expected 0 command line arguments, found ' . + "$args\n$USAGE"; + + my @cuban_primes; + + for (my ($n, $hex_number) = (1, 0); $hex_number <= $MAX; ++$n) + { + my $triple = 3 * $n; + $hex_number = $triple * $n - $triple + 1; + + push @cuban_primes, $hex_number if is_prime( $hex_number ); + } + + splice @cuban_primes, -1, 1 if $cuban_primes[ -1 ] > $MAX; + + printf "The %d first-series Cuban Primes <= %d:\n\n %s\n", + scalar @cuban_primes, $MAX, join ', ', @cuban_primes; +} + +#------------------------------------------------------------------------------ +sub is_prime +#------------------------------------------------------------------------------ +{ + # On first call, create a Sieve of Eratosthenes in the range 0 .. $MAX + + state @is_prime = (0, 0, (1) x ($MAX - 1)); # 0, 1, (2 .. $MAX) + + if (state $first_call = 1) + { + $first_call = 0; + + for my $n (0 .. $MAX) + { + next unless $is_prime[ $n ]; # Skip non-primes + + for (my $i = 2 * $n; $i <= $MAX; $i += $n) + { + $is_prime[ $i ] = 0; + } + } + } + + my ($n) = @_; + + return $is_prime[ $n ]; # Sieve look-up +} + +############################################################################### diff --git a/challenge-158/athanasius/raku/ch-1.raku b/challenge-158/athanasius/raku/ch-1.raku new file mode 100644 index 0000000000..2cda927072 --- /dev/null +++ b/challenge-158/athanasius/raku/ch-1.raku @@ -0,0 +1,107 @@ +use v6d; + +############################################################################### +=begin comment + +Perl Weekly Challenge 158 +========================= + +TASK #1 +------- +*Additive Primes* + +Submitted by: Mohammad S Anwar + +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 + +=end comment +############################################################################### + +#--------------------------------------# +# Copyright © 2022 PerlMonk Athanasius # +#--------------------------------------# + +#============================================================================== +=begin comment + +Algorithm +--------- +1. Generate primes in the required range using the Sieve of Eratosthenes [3] +2. For each prime in the sieve: + - sum the digits + - if the sum is a prime number recorded in the sieve, add it to the list of + additive primes +3. Output the list of additive primes + +References +---------- +[1] "A046704 Additive primes: sum of digits is a prime.", OEIS, + https://oeis.org/A046704 +[2] Reinhard Zumkeller, "Table of n, a(n) for n = 1..10000", OEIS, + https://oeis.org/A046704/b046704.txt +[3] "Sieve of Eratosthenes", Wikipedia, + https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes + +=end comment +#============================================================================== + +my UInt constant $MAX = 100; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + "\nChallenge 158, Task #1: Additive Primes (Raku)\n".put; +} + +#============================================================================== +sub MAIN() +#============================================================================== +{ + # Sieve: + my Bool @is-prime = False, False, |(True xx ($MAX - 1)); # 0, 1, (2..$MAX) + + for 0 .. $MAX -> UInt $n # Find the primes + { + next unless @is-prime[ $n ]; # Skip non-primes + + loop (my UInt $i = 2 * $n; $i <= $MAX; $i += $n) + { + @is-prime[ $i ] = False; + } + } + + my UInt @additive-primes; + + for 0 .. $MAX -> UInt $p + { + next unless @is-prime[ $p ]; # Skip non-primes + + my UInt $sum = [+] $p.split: '', :skip-empty; # Sum the digits + + @additive-primes.push: $p if @is-prime[ $sum ]; + } + + "Additive primes <= %d:\n\n %s\n".printf: + $MAX, @additive-primes.join: ', '; +} + +#------------------------------------------------------------------------------ +sub USAGE() +#------------------------------------------------------------------------------ +{ + my Str $usage = $*USAGE; + + $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/; + + $usage.put; +} + +############################################################################## diff --git a/challenge-158/athanasius/raku/ch-2.raku b/challenge-158/athanasius/raku/ch-2.raku new file mode 100644 index 0000000000..bf430d844e --- /dev/null +++ b/challenge-158/athanasius/raku/ch-2.raku @@ -0,0 +1,100 @@ +use v6d; + +############################################################################### +=begin comment + +Perl Weekly Challenge 158 +========================= + +TASK #2 +------- +*First Series Cuban Primes* + +Submitted by: Mohammad S Anwar + +Write a script to compute first series Cuban Primes <= 1000. Please refer +[ https://en.wikipedia.org/wiki/Cuban_prime |wikipedia page] for more informa- +tions. + +Output + + 7, 19, 37, 61, 127, 271, 331, 397, 547, 631, 919. + +=end comment +############################################################################### + +#--------------------------------------# +# Copyright © 2022 PerlMonk Athanasius # +#--------------------------------------# + +#============================================================================== +=begin comment + +Algorithm +--------- +The first-series Cuban Primes are a subset of the centred hexagonal (or "hex") +numbers [1, 3]. So, the algorithm begins by generating consecutive hex numbers, +using the formula: + + H(n) = 3n² - 3n + 1 + +where H(n) is the nth centered hexagonal number [2]. + +As each hex number is generated, it is tested for primality using Raku's built- +in is-prime() method. Hex numbers found to be prime are stored. + +When all hex numbers in the target range have been evaluated, the stored prime +hex numbers are output as the required first-series Cuban Primes. + +References +---------- +[1] "A002407 Cuban primes: primes which are the difference of two consecutive + cubes.", OEIS, https://oeis.org/A002407 +[2] "Centered hexagonal number", Wikipedia, + https://en.wikipedia.org/wiki/Centered_hexagonal_number +[3] "Cuban prime", Wikipedia, https://en.wikipedia.org/wiki/Cuban_prime + +=end comment +#============================================================================== + +my UInt constant $MAX = 1_000; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + "\nChallenge 158, Task #2: First Series Cuban Primes (Raku)\n".put; +} + +#============================================================================== +sub MAIN() +#============================================================================== +{ + my UInt @cuban-primes; + + loop (my UInt ($n, $hex-number) = 1, 0; $hex-number <= $MAX; ++$n) + { + my UInt $triple = 3 * $n; + $hex-number = $triple * $n - $triple + 1; + + @cuban-primes.push: $hex-number if $hex-number.is-prime; + } + + @cuban-primes.splice: *-1, 1 if @cuban-primes[ *-1 ] > $MAX; + + "The %d first-series Cuban Primes <= %d:\n\n %s\n".printf: + +@cuban-primes, $MAX, @cuban-primes.join: ', '; +} + +#------------------------------------------------------------------------------ +sub USAGE() +#------------------------------------------------------------------------------ +{ + my Str $usage = $*USAGE; + + $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/; + + $usage.put; +} + +############################################################################## |
