aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com>2022-03-30 17:34:56 +1000
committerPerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com>2022-03-30 17:34:56 +1000
commitdbbcfafcc2dd438437d3cecd819276662b19f3aa (patch)
treec1b3d49733fea05e5ec9c88b6225ccb7307607b6
parent5002c9e2bcf431285b74dd9fc51d0f62843abdb1 (diff)
downloadperlweeklychallenge-club-dbbcfafcc2dd438437d3cecd819276662b19f3aa.tar.gz
perlweeklychallenge-club-dbbcfafcc2dd438437d3cecd819276662b19f3aa.tar.bz2
perlweeklychallenge-club-dbbcfafcc2dd438437d3cecd819276662b19f3aa.zip
Perl & Raku solutions to Tasks 1 & 2 for Week 158
-rw-r--r--challenge-158/athanasius/perl/ch-1.pl106
-rw-r--r--challenge-158/athanasius/perl/ch-2.pl129
-rw-r--r--challenge-158/athanasius/raku/ch-1.raku107
-rw-r--r--challenge-158/athanasius/raku/ch-2.raku100
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;
+}
+
+##############################################################################