aboutsummaryrefslogtreecommitdiff
path: root/challenge-168
diff options
context:
space:
mode:
authordrbaggy <js5@sanger.ac.uk>2022-06-12 10:24:55 +0100
committerdrbaggy <js5@sanger.ac.uk>2022-06-12 10:24:55 +0100
commitbfb2f77baa587efd8a99c991d81a5c1f24136209 (patch)
treea9386e4210d84815cb694a11e456a7fbc056fcc2 /challenge-168
parent3c1dd872be61bf5ef7b1a974ab7b3ff09ff0225d (diff)
parent79ce82da7c249f4af4572b7f951bca0adc45acbe (diff)
downloadperlweeklychallenge-club-bfb2f77baa587efd8a99c991d81a5c1f24136209.tar.gz
perlweeklychallenge-club-bfb2f77baa587efd8a99c991d81a5c1f24136209.tar.bz2
perlweeklychallenge-club-bfb2f77baa587efd8a99c991d81a5c1f24136209.zip
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'challenge-168')
-rw-r--r--challenge-168/cheok-yin-fung/perl/ch-1.pl29
-rw-r--r--challenge-168/cheok-yin-fung/perl/ch-2.pl72
-rw-r--r--challenge-168/dave-jacoby/blog.txt3
-rw-r--r--challenge-168/dave-jacoby/perl/ch-1.pl28
-rw-r--r--challenge-168/dave-jacoby/perl/ch-2.pl49
-rw-r--r--challenge-168/laurent-rosenfeld/blog.txt1
-rw-r--r--challenge-168/laurent-rosenfeld/perl/ch-1.pl33
-rw-r--r--challenge-168/laurent-rosenfeld/raku/ch-1.raku1
-rw-r--r--challenge-168/lubos-kolouch/perl/ch-2.pl24
-rw-r--r--challenge-168/lubos-kolouch/python/ch-2.py19
-rwxr-xr-xchallenge-168/mattneleigh/perl/ch-1.pl99
-rwxr-xr-xchallenge-168/mattneleigh/perl/ch-2.pl141
-rw-r--r--challenge-168/polettix/blog.txt1
-rw-r--r--challenge-168/polettix/blog1.txt1
-rw-r--r--challenge-168/polettix/perl/ch-1.pl21
-rw-r--r--challenge-168/polettix/perl/ch-2.pl17
-rw-r--r--challenge-168/polettix/perl/cpanfile1
-rw-r--r--challenge-168/polettix/perl/cpanfile.snapshot38
-rw-r--r--challenge-168/polettix/raku/ch-1.raku28
-rw-r--r--challenge-168/polettix/raku/ch-2.raku31
-rwxr-xr-xchallenge-168/steve-g-lynn/julia/ch-2.jl43
-rwxr-xr-xchallenge-168/steve-g-lynn/perl/ch-2.pl52
-rwxr-xr-xchallenge-168/steve-g-lynn/raku/ch-2.p6124
23 files changed, 719 insertions, 137 deletions
diff --git a/challenge-168/cheok-yin-fung/perl/ch-1.pl b/challenge-168/cheok-yin-fung/perl/ch-1.pl
new file mode 100644
index 0000000000..faf90a9bb3
--- /dev/null
+++ b/challenge-168/cheok-yin-fung/perl/ch-1.pl
@@ -0,0 +1,29 @@
+#!/usr/bin/perl
+# The Weekly Challenge 168
+# Task 1 Perrin Prime
+use v5.24.0;
+use warnings;
+use List::Util qw/none/;
+use Math::Prime::Util qw/is_prime/;
+
+my @perrin_primes = (2,3);
+my ($ppnm3,$ppnm2,$ppnm1, $ppn) = (3,0,2,3);
+
+while (scalar @perrin_primes < 13) {
+ if (is_prime($ppn) == 2) {
+ push @perrin_primes, $ppn if none {$_ == $ppn} @perrin_primes;
+ say $ppn;
+ }
+ $ppnm3 = $ppnm2;
+ $ppnm2 = $ppnm1;
+ $ppnm1 = $ppn;
+ $ppn = $ppnm2 + $ppnm3;
+}
+
+say join ", ", @perrin_primes;
+
+# time:
+# real 0m0.025s
+# user 0m0.017s
+# sys 0m0.009s
+
diff --git a/challenge-168/cheok-yin-fung/perl/ch-2.pl b/challenge-168/cheok-yin-fung/perl/ch-2.pl
new file mode 100644
index 0000000000..00406d25ef
--- /dev/null
+++ b/challenge-168/cheok-yin-fung/perl/ch-2.pl
@@ -0,0 +1,72 @@
+#!/usr/bin/perl
+# The Weekly Challenge 168
+# Task 2 Home Prime
+# Usage: ch-2.pl [integer > 1]
+use v5.24.0;
+use warnings;
+use Math::Prime::Util qw/is_prime next_prime/;
+use Math::BigInt;
+
+say hp($ARGV[0]) if defined($ARGV[0]) && $ARGV[0] != 1;
+
+
+
+sub hp {
+ my_hp($_[0],0);
+}
+
+
+
+sub my_hp {
+ my $num = $_[0];
+ my $recur_depth = $_[1];
+ die "Number involved too large.\n"
+ if
+ Math::BigInt->new("18446744073709551616") # 2**64
+ ->ble( Math::BigInt->new($num) );
+
+
+ if (is_prime($num) == 2) {
+ return $num;
+ }
+
+ die "Walk so far but still cannot get result. :(\n" if $recur_depth > 20;
+
+ my @factors = ();
+ my $p = 2;
+ while ($num != 1) {
+ if (!($num % $p)) {
+ push @factors, $p;
+ $num /= $p;
+ }
+ else {
+ $p = next_prime($p);
+ }
+ if ($p > sqrt $num) {
+ say "useful";
+ push @factors, $num;
+ last;
+ }
+ }
+ my $nxt = join "", @factors;
+ say " $nxt";
+ return my_hp($nxt, ++$recur_depth);
+}
+
+use Test::More tests => 8;
+# test data from OEIS
+ok hp(10) == 773;
+ok hp(24) == 331_319;
+ok hp(32) == 241_271;
+ok hp(40) == 3314192745739;
+ok hp(44) == 22815088913;
+ok hp(45) == 3_411_949;
+
+# bigger cases;
+ok hp( 8) == 3331113965338635107;
+ok hp(20) == 3318308475676071413;
+
+# real 0m5.553s
+# user 0m5.535s
+# sys 0m0.016s
+
diff --git a/challenge-168/dave-jacoby/blog.txt b/challenge-168/dave-jacoby/blog.txt
new file mode 100644
index 0000000000..b28b04f643
--- /dev/null
+++ b/challenge-168/dave-jacoby/blog.txt
@@ -0,0 +1,3 @@
+
+
+
diff --git a/challenge-168/dave-jacoby/perl/ch-1.pl b/challenge-168/dave-jacoby/perl/ch-1.pl
new file mode 100644
index 0000000000..39a1510b86
--- /dev/null
+++ b/challenge-168/dave-jacoby/perl/ch-1.pl
@@ -0,0 +1,28 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use experimental qw{ say postderef signatures state };
+
+my @perrin = ( 3, 0, 2 );
+my %perrin_primes;
+$perrin_primes{2} = 1;
+$perrin_primes{3} = 1;
+
+while ( scalar keys %perrin_primes < 13 ) {
+ my $x = $perrin[-2] + $perrin[-3];
+ push @perrin, $x;
+ $perrin_primes{$x} = 1 if is_prime($x);
+}
+
+say join ' ', sort { $a <=> $b } keys %perrin_primes;
+exit;
+
+sub is_prime ($n) {
+ die "Bad number $n" unless length $n;
+ return 0 if $n == 0;
+ return 0 if $n == 1;
+ for ( 2 .. sqrt $n ) { return 0 unless $n % $_ }
+ return 1;
+}
+
diff --git a/challenge-168/dave-jacoby/perl/ch-2.pl b/challenge-168/dave-jacoby/perl/ch-2.pl
new file mode 100644
index 0000000000..1d101a36a4
--- /dev/null
+++ b/challenge-168/dave-jacoby/perl/ch-2.pl
@@ -0,0 +1,49 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use experimental qw{ say postderef signatures state };
+
+use Carp;
+use Try::Tiny;
+use Math::Prime::XS qw{ is_prime };
+
+$| = 1;
+
+my @n = @ARGV;
+push @n, 10 unless scalar @ARGV;
+
+for my $i (@n) {
+ try {
+ my $p = get_home_prime($i);
+ say join "\t", '-', $i, $p;
+ }
+ catch {
+ say $_;
+ };
+}
+
+sub get_home_prime($n) {
+ my $p = $n;
+ while ( !is_prime($p) ) {
+ my @factors = get_factors($p);
+ $p = join '', @factors;
+ print qq{$p };
+ # croak 'Too Big, Too Slow' if length $p > 10;
+ }
+ say '';
+ return $p;
+}
+
+sub get_factors( $n ) {
+ my @factors;
+ for my $i ( 2 .. $n ) {
+ next unless $n % $i == 0;
+ while ( $n % $i == 0 ) {
+ push @factors, $i;
+ $n = $n / $i;
+ }
+ }
+ return @factors;
+}
+
diff --git a/challenge-168/laurent-rosenfeld/blog.txt b/challenge-168/laurent-rosenfeld/blog.txt
new file mode 100644
index 0000000000..388761ba75
--- /dev/null
+++ b/challenge-168/laurent-rosenfeld/blog.txt
@@ -0,0 +1 @@
+http://blogs.perl.org/users/laurent_r/2022/06/perl-weekly-challenge-168-perrin-primes.html
diff --git a/challenge-168/laurent-rosenfeld/perl/ch-1.pl b/challenge-168/laurent-rosenfeld/perl/ch-1.pl
new file mode 100644
index 0000000000..906b341080
--- /dev/null
+++ b/challenge-168/laurent-rosenfeld/perl/ch-1.pl
@@ -0,0 +1,33 @@
+use strict;
+use warnings;
+use feature "say";
+
+my @perrin = (3, 0, 2);
+my @result = (2, 3);
+my %seen = map { $_ => 1 } @result;
+while (1) {
+ my $new_item = $perrin[-3] + $perrin[-2];
+ push @perrin, $new_item;
+ if (is_prime($new_item)) {
+ push @result, $new_item unless $seen{$new_item};
+ $seen{$new_item} = 1;
+ last if @result > 12;
+ }
+}
+say join " ", sort { $a <=> $b } @result;
+
+sub is_prime {
+ my $n = shift;
+ return 1 if $n == 2;
+ return 0 if $n % 2 == 0;
+ return 0 if $n == 1;
+
+ my $p = 3;
+ my $sqrt = sqrt $n;
+ while ($p <= $sqrt) {
+ # return 1 if $p >= $n;
+ return 0 if $n % $p == 0;
+ $p += 2;
+ }
+ return 1;
+}
diff --git a/challenge-168/laurent-rosenfeld/raku/ch-1.raku b/challenge-168/laurent-rosenfeld/raku/ch-1.raku
new file mode 100644
index 0000000000..f00ae2d3ef
--- /dev/null
+++ b/challenge-168/laurent-rosenfeld/raku/ch-1.raku
@@ -0,0 +1 @@
+say (unique grep {.is-prime}, (3, 0, 2, -> $a, $b, $c { $a + $b } ... ∞))[0..12].sort;
diff --git a/challenge-168/lubos-kolouch/perl/ch-2.pl b/challenge-168/lubos-kolouch/perl/ch-2.pl
new file mode 100644
index 0000000000..1390fba896
--- /dev/null
+++ b/challenge-168/lubos-kolouch/perl/ch-2.pl
@@ -0,0 +1,24 @@
+use strict;
+use warnings;
+use Math::Prime::Util qw/is_prime factor/;
+
+sub home_prime {
+ my $n = shift;
+
+ while ( !is_prime($n) ) {
+ my @factors = factor($n);
+ my $sum = '';
+ foreach my $factor (@factors) {
+ $sum .= $factor;
+ }
+ $n = $sum;
+ }
+
+ return $n;
+}
+
+use Test::More;
+
+is( home_prime(2), 2 );
+is( home_prime(10), 773 );
+done_testing;
diff --git a/challenge-168/lubos-kolouch/python/ch-2.py b/challenge-168/lubos-kolouch/python/ch-2.py
new file mode 100644
index 0000000000..16094e836d
--- /dev/null
+++ b/challenge-168/lubos-kolouch/python/ch-2.py
@@ -0,0 +1,19 @@
+from sympy import factorint, isprime
+
+
+def home_prime(n):
+
+ while not isprime(n):
+ factors = factorint(n)
+
+ my_sum = ""
+ for (my_factor, repetition) in factors.items():
+ my_sum += str(my_factor) * repetition
+
+ n = int(my_sum)
+
+ return n
+
+
+assert home_prime(2) == 2
+assert home_prime(10) == 773
diff --git a/challenge-168/mattneleigh/perl/ch-1.pl b/challenge-168/mattneleigh/perl/ch-1.pl
new file mode 100755
index 0000000000..9ea3014572
--- /dev/null
+++ b/challenge-168/mattneleigh/perl/ch-1.pl
@@ -0,0 +1,99 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use English;
+
+################################################################################
+# Begin main execution
+################################################################################
+
+my @perrin = (3, 0, 2);
+my %perrin_primes = (
+ 3 => 1,
+ 2 => 1
+);
+my $num = 13;
+
+while(scalar(keys(%perrin_primes)) < $num){
+ next_perrin(\@perrin, 1);
+ $perrin_primes{$perrin[$#perrin]} = 1
+ if(is_prime($perrin[$#perrin]));
+}
+
+print("\n");
+printf(
+ "f(%d) = [%s]\n",
+ $num,
+ join(", ", sort({ $a <=> $b } keys(%perrin_primes)))
+);
+print("\n");
+
+exit(0);
+################################################################################
+# End main execution; subroutines follow
+################################################################################
+
+
+
+################################################################################
+# Calculate the next number in the Perrin sequence, adding it to an existing
+# list of Perrin numbers; see https://en.wikipedia.org/wiki/Perrin_number for
+# details about this type of number
+# Takes one or two arguments:
+# * A ref to a list of Perrin numbers; upon first call to this function, this
+# list must be [ 3, 0, 2 ]
+# * An agument that, if defined, will cause the first member of the list to be
+# removed after the new one is added, preventing the list from growing
+# Returns no meaningful value
+################################################################################
+sub next_perrin{
+ my $perrin = shift();
+
+ # Add the next number in the sequence
+ push(
+ @{$perrin},
+ $perrin->[$#$perrin - 2] + $perrin->[$#$perrin - 1]
+ );
+
+ # If specified, toss out the oldest number
+ shift(@{$perrin})
+ if(defined(shift()));
+
+}
+
+
+
+################################################################################
+# Determine whether a given integer N is prime
+# Takes one argument:
+# * The integer N
+# Returns on success:
+# * 1 if N is prime
+# * 0 if N is not prime
+# NOTE: If N is less than zero, it will always be considered nonprime
+################################################################################
+sub is_prime{
+ my $n = int(shift());
+
+ my $i;
+
+ # Take care of a few easy cases
+ return(1)
+ if(($n == 2) || ($n == 3));
+ return(0)
+ if(($n <= 1) || !($n % 2) || !($n % 3));
+
+ # See if certain factors divide evenly
+ for($i = 5; $i * $i <= $n; $i += 6){
+ if(!($n % $i) || !($n % ($i + 2))){
+ return(0);
+ }
+ }
+
+ return(1);
+
+}
+
+
+
diff --git a/challenge-168/mattneleigh/perl/ch-2.pl b/challenge-168/mattneleigh/perl/ch-2.pl
new file mode 100755
index 0000000000..73a5a0962f
--- /dev/null
+++ b/challenge-168/mattneleigh/perl/ch-2.pl
@@ -0,0 +1,141 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use English;
+
+################################################################################
+# Begin main execution
+################################################################################
+
+my $n = 10;
+
+# If you have some time on your hands...
+# $n = 8;
+
+print("\n");
+printf("HP(%d) = %d\n", $n, calculate_home_prime($n));
+print("\n");
+
+exit(0);
+################################################################################
+# End main execution; subroutines follow
+################################################################################
+
+
+
+################################################################################
+# Calculate the home prime of a given integer; see
+# https://en.wikipedia.org/wiki/Home_prime for details about this type of
+# number
+# Takes one argument:
+# * An integer N, which must be at least two (2)
+# Returns on success:
+# * The home prime of N
+# Returns on error:
+# * undef if N is less than two (2)
+# NOTE: For certain values of N, this calculation can take wholly unreasonable
+# amounts of time
+################################################################################
+sub calculate_home_prime{
+ my $n = int(shift());
+
+ return(undef)
+ if($n < 2);
+
+ # Loop until $n is prime
+ until(is_prime($n)){
+ my @factors;
+
+ # Get the prime factors of $n, and concatenate
+ # them into a new $n
+ prime_factorize_number($n, \@factors);
+ $n = join("", @factors);
+ }
+
+ return($n);
+
+}
+
+
+
+################################################################################
+# Find the prime factorization of a given integer
+# Takes two arguments:
+# * The integer N to examine and factor
+# * A ref to a list that will be populated with prime factors in ascending
+# order; any previous contents will be deleted
+# Returns no meaningful value
+################################################################################
+sub prime_factorize_number{
+ use POSIX;
+
+ my $n = int(shift());
+ my $factors = shift();
+
+ # Clobber existing list contents if any
+ splice(@{$factors}, 0)
+ if(scalar(@{$factors}));
+
+ # Loop until $n is prime
+ until(is_prime($n)){
+ # $n is not prime; set an upper bound on
+ # our factor search
+ my $i;
+ my $max = ceil(sqrt($n));
+
+ # Loop until we find prime $i that
+ # divides evenly into $n
+ for($i=2; $i<=$max; $i++){
+ next unless(is_prime($i));
+ last unless($n % $i);
+ }
+
+ # Store the new prime factor $i and
+ # divide $n by it
+ push(@{$factors}, $i);
+ $n /= $i;
+
+ }
+
+ # Store $n, which by now is the last prime
+ # factor of the originally-supplied argument
+ push(@{$factors}, $n);
+
+}
+
+
+
+################################################################################
+# Determine whether a given integer N is prime
+# Takes one argument:
+# * The integer N
+# Returns on success:
+# * 1 if N is prime
+# * 0 if N is not prime
+# NOTE: If N is less than zero, it will always be considered nonprime
+################################################################################
+sub is_prime{
+ my $n = int(shift());
+
+ my $i;
+
+ # Take care of a few easy cases
+ return(1)
+ if(($n == 2) || ($n == 3));
+ return(0)
+ if(($n <= 1) || !($n % 2) || !($n % 3));
+
+ # See if certain factors divide evenly
+ for($i = 5; $i * $i <= $n; $i += 6){
+ if(!($n % $i) || !($n % ($i + 2))){
+ return(0);
+ }
+ }
+
+ return(1);
+
+}
+
+
+
diff --git a/challenge-168/polettix/blog.txt b/challenge-168/polettix/blog.txt
new file mode 100644
index 0000000000..f6337130ae
--- /dev/null
+++ b/challenge-168/polettix/blog.txt
@@ -0,0 +1 @@
+https://github.polettix.it/ETOOBUSY/2022/06/08/pwc168-perrin-prime/
diff --git a/challenge-168/polettix/blog1.txt b/challenge-168/polettix/blog1.txt
new file mode 100644
index 0000000000..ad226cc866
--- /dev/null
+++ b/challenge-168/polettix/blog1.txt
@@ -0,0 +1 @@
+https://github.polettix.it/ETOOBUSY/2022/06/09/pwc168-home-prime/
diff --git a/challenge-168/polettix/perl/ch-1.pl b/challenge-168/polettix/perl/ch-1.pl
new file mode 100644
index 0000000000..e4952fb0ed
--- /dev/null
+++ b/challenge-168/polettix/perl/ch-1.pl
@@ -0,0 +1,21 @@
+#!/usr/bin/env perl
+use v5.24;
+use warnings;
+use experimental 'signatures';
+no warnings 'experimental::signatures';
+
+use ntheory 'is_prime';
+
+my $n = shift // 13;
+say join ', ', perrin_primes($n);
+
+sub perrin_primes ($n) {
+ my @pps = (2, 3, 5);
+ my @state = (2, 5, 5);
+ while (@pps < $n) {
+ push @state, my $candidate = $state[0] + $state[1];
+ shift @state;
+ push @pps, $candidate if is_prime($candidate);
+ }
+ return @pps;
+}
diff --git a/challenge-168/polettix/perl/ch-2.pl b/challenge-168/polettix/perl/ch-2.pl
new file mode 100644
index 0000000000..24a1dd1255
--- /dev/null
+++ b/challenge-168/polettix/perl/ch-2.pl
@@ -0,0 +1,17 @@
+#!/usr/bin/env perl
+use v5.24;
+use warnings;
+use experimental 'signatures';
+no warnings 'experimental::signatures';
+
+use ntheory qw< factor >;
+
+my $n = shift // 10;
+say home_prime($n);
+
+sub home_prime {
+ my $next = join '', factor($_[0]);
+ return $next if $next eq $_[0];
+ $_[0] = $next;
+ goto &home_prime;
+}
diff --git a/challenge-168/polettix/perl/cpanfile b/challenge-168/polettix/perl/cpanfile
new file mode 100644
index 0000000000..94ac365d6f
--- /dev/null
+++ b/challenge-168/polettix/perl/cpanfile
@@ -0,0 +1 @@
+requires 'ntheory';
diff --git a/challenge-168/polettix/perl/cpanfile.snapshot b/challenge-168/polettix/perl/cpanfile.snapshot
new file mode 100644
index 0000000000..2fd600a3af
--- /dev/null
+++ b/challenge-168/polettix/perl/cpanfile.snapshot
@@ -0,0 +1,38 @@
+# carton snapshot format: version 1.0
+DISTRIBUTIONS
+ Math-Prime-Util-0.73
+ pathname: D/DA/DANAJ/Math-Prime-Util-0.73.tar.gz
+ provides:
+ Math::Prime::Util 0.73
+ Math::Prime::Util::ChaCha 0.73
+ Math::Prime::Util::Entropy 0.73
+ Math::Prime::Util::MemFree 0.73
+ Math::Prime::Util::PP 0.73
+ Math::Prime::Util::PrimeArray 0.73
+ Math::Prime::Util::PrimeIterator 0.73
+ ntheory 0.73
+ requirements:
+ Carp 0
+ Config 0
+ Exporter 5.57
+ ExtUtils::MakeMaker 0
+ Math::BigFloat 1.59
+ Math::BigInt 1.88
+ Math::Prime::Util::GMP 0.50
+ Tie::Array 0
+ XSLoader 0.01
+ base 0
+ constant 0
+ perl 5.006002
+ Math-Prime-Util-GMP-0.52
+ pathname: D/DA/DANAJ/Math-Prime-Util-GMP-0.52.tar.gz
+ provides:
+ Math::Prime::Util::GMP 0.52
+ requirements:
+ Carp 0
+ Exporter 5.57
+ ExtUtils::MakeMaker 0
+ Fcntl 0
+ XSLoader 0.01
+ base 0
+ perl 5.006002
diff --git a/challenge-168/polettix/raku/ch-1.raku b/challenge-168/polettix/raku/ch-1.raku
new file mode 100644
index 0000000000..28f3b1fb86
--- /dev/null
+++ b/challenge-168/polettix/raku/ch-1.raku
@@ -0,0 +1,28 @@
+#!/usr/bin/env raku
+use v6;
+
+class PerrinSequence {
+ has @!state = [3, 0, 2];
+ method get () {
+ @!state.push(@!state[0] + @!state[1]);
+ return @!state.shift;
+ }
+}
+
+multi sub MAIN (1) { put 2 }
+
+multi sub MAIN (2) { put '2, 3' }
+
+multi sub MAIN (3) { put '2, 3, 5' }
+
+multi sub MAIN (Int:D $n is copy where * > 3 = 13) {
+ my $ps = PerrinSequence.new;
+ $ps.get for 1..7;
+ my @n-primes = gather while $n > 3 {
+ my $candidate = $ps.get;
+ next unless $candidate.is-prime;
+ take $candidate;
+ --$n;
+ }
+ [2, 3, 5, |@n-primes].join(', ').put;
+}
diff --git a/challenge-168/polettix/raku/ch-2.raku b/challenge-168/polettix/raku/ch-2.raku
new file mode 100644
index 0000000000..5de2d6efd4
--- /dev/null
+++ b/challenge-168/polettix/raku/ch-2.raku
@@ -0,0 +1,31 @@
+#!/usr/bin/env raku
+use v6;
+sub MAIN (Int:D $n where * > 1 = 10) { put home-prime($n) }
+
+sub home-prime ($n is copy) {
+ loop {
+ my $m = factors($n).join('').Int;
+ return $n if $n == $m;
+ $n = $m;
+ }
+}
+
+sub factors (Int $remainder is copy) {
+ return 1 if $remainder <= 1;
+ state @primes = 2, 3, 5, -> $n is copy {
+ repeat { $n += 2 } until $n %% none @primes ... { $_ * $_ >= $n }
+ $n;
+ } ... *;
+ gather for @primes -> $factor {
+ if $factor * $factor > $remainder {
+ take $remainder if $remainder > 1;
+ last;
+ }
+
+ # How many times can we divide by this prime?
+ while $remainder %% $factor {
+ take $factor;
+ last if ($remainder div= $factor) === 1;
+ }
+ }
+}
diff --git a/challenge-168/steve-g-lynn/julia/ch-2.jl b/challenge-168/steve-g-lynn/julia/ch-2.jl
index 19d4c7d498..0828857250 100755
--- a/challenge-168/steve-g-lynn/julia/ch-2.jl
+++ b/challenge-168/steve-g-lynn/julia/ch-2.jl
@@ -1,15 +1,56 @@
#! /usr/bin/julia
+#time (bash) output: with homeprime.([10,16,20,48,65,96])
+#real 0m41.340s
+#user 0m41.149s
+#sys 0m0.493s
+
+#-- without homeprime(96):
+#real 0m4.744s
+#user 0m4.745s
+#sys 0m0.467s
+
+#-- without .homeprime.([96,65])
+#real 0m1.072s
+#user 0m1.138s
+#sys 0m0.419s
+
+#-- without .homeprime.([96,65,48])
+#real 0m1.002s
+#user 0m1.095s
+#sys 0m0.384s
+
+
+
using Primes
function homeprime(n::Int64)
+ return homeprime(BigInt(n))
+end
+
+function homeprime(n::BigInt)
ncopy=n
while (!isprime(ncopy))
- ncopy=parse(Int64,join(factor(Vector,ncopy)))
+ ncopy=parse(BigInt,join(factor(Vector,ncopy)))
end
return ncopy
end
+println(homeprime(10))
+#773
+
println(homeprime(16))
#31636373
+println(homeprime(20))
+#3318308475676071413
+
+println(homeprime(48))
+#6161791591356884791277
+
+println(homeprime(65))
+#1381321118321175157763339900357651
+
+println(homeprime(96))
+#172929671097972226356946608292031596899264419
+
diff --git a/challenge-168/steve-g-lynn/perl/ch-2.pl b/challenge-168/steve-g-lynn/perl/ch-2.pl
index d1f6f0aced..0548ac1ebc 100755
--- a/challenge-168/steve-g-lynn/perl/ch-2.pl
+++ b/challenge-168/steve-g-lynn/perl/ch-2.pl
@@ -1,37 +1,35 @@
#!/usr/bin/perl
-use Math::Prime::XS qw(is_prime sieve_primes);
+#time (bash) output:
+#real 0m0.026s
+#user 0m0.019s
+#sys 0m0.007s
+# but this fast time degrades sharply with larger problems
+#
+# real is 0m45.199s if home_prime(48) also printed
+# real is 5m5.662s if home_prime of 48 and 65 also printed
+# real is 8m50.059s if home_prime of 48, 65 and 96 also printed
+#
+# probably some slowdown in factor(.) for factors of very large primes
+
+use Math::Prime::Util qw(is_prime factor);
+
+print &home_prime(10),"\n";
+#773
print &home_prime(16),"\n";
-#-- should be 31636373 [wikipedia example]
+#31636373
+
+print &home_prime(20),"\n";
+#3318308475676071413
sub home_prime {
- local ($n)=@_;
- while (1){
- $n=&factors($n);
- (is_prime($n)) && last;
- }
- return $n;
+ my ($n)=@_;
+ is_prime($n) && return $n;
+ return &home_prime(join('',sort{$a<=>$b}(factor($n))));
}
-sub factors {
- #--return concatenated prime factors of a number n
- local ($n)=@_;
- local @primes=sieve_primes($n);
- local $retstring="";
-
- if (is_prime($n)){
- return $n;
- }
- else {
- foreach $prime (sort{$a<=>$b} @primes){
- while ( ($n % $prime) == 0){
- $n /= $prime;
- $retstring .= $prime;
- }
- }
- }
- return $retstring;
-}
+1;
+
diff --git a/challenge-168/steve-g-lynn/raku/ch-2.p6 b/challenge-168/steve-g-lynn/raku/ch-2.p6
index bfe46ec923..09cbc4412b 100755
--- a/challenge-168/steve-g-lynn/raku/ch-2.p6
+++ b/challenge-168/steve-g-lynn/raku/ch-2.p6
@@ -1,126 +1,32 @@
#!/usr/bin/raku
#time (bash command):
-#real 0m0.490s
-#user 0m0.729s
-#sys 0m0.056s
+#real 0m0.312s
+#user 0m0.382s
+#sys 0m0.054s
+#time if homeprime(48), homeprime(65) and homeprime(96) are also printed:
+#real 2m23.931s
+#user 2m23.527s
+#sys 0m0.071s
+#
+# ( real 11.512s with homeprime (10,16,20,48,65)
+# real 0.922s with homeprime (10,16,20,48) )
-# acknowledgement:
-
-# I improved the previous grossly inefficient version
-# (> 1 min script run time) after looking
-# at the raku and python submissions from Roger Bell-West
-
+use Prime::Factor;
say homeprime(10);
#773
say homeprime(16);
#31636373
+say homeprime(20);
+#3318308475676071413
#-- sub for home prime
-sub homeprime(Int $n) returns Int {
+sub homeprime(Int $n where ($n > 1)) returns Int {
$n.Int.is-prime && return $n;
- my $ncopy=$n;
- while (1) {
- my $last=$ncopy;
- $ncopy=factor($ncopy);
- ($ncopy==$last) && last;
- }
- return $ncopy;
-}
-
-#--sub for factorizing
-
-multi sub factor (1) returns Int {1}
-
-multi sub factor (Int $n where $n > 1) returns Int {
-#-- returns the concatenated prime factors as an int
- $n.Int.is-prime && (return $n.Int );
- my $sqrt_n = sqrt($n).Int+1;
- my @primes=find_primes($sqrt_n);
- my @factors=();
-
- my $retstring="";
- my $ncopy=$n;
-
- for @primes -> $prime {
- while ( ($ncopy % $prime)==0) {
- $ncopy /= $prime;
- push @factors, $prime;
- }
- }
- ($ncopy > 1) && push @factors, $ncopy;
- #-- any factor bigger than sqrt(n) is a prime factor
- $retstring = @factors.list.join;
-
- return $retstring.Int;
+ return homeprime(([~] prime-factors($n)).Int);
}