aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2021-11-18 19:41:51 +0000
committerGitHub <noreply@github.com>2021-11-18 19:41:51 +0000
commitfea16493802aaa652cbbf246221e7425a2a0a536 (patch)
tree8cde6838b2ac60e53f46c0c968313b5294cf5cd5
parent24273ec3ac38e5d069856336fdb86b31d3029d6e (diff)
parent913810214acef4eaeb99f1ccb16c4f03ebd1bd61 (diff)
downloadperlweeklychallenge-club-fea16493802aaa652cbbf246221e7425a2a0a536.tar.gz
perlweeklychallenge-club-fea16493802aaa652cbbf246221e7425a2a0a536.tar.bz2
perlweeklychallenge-club-fea16493802aaa652cbbf246221e7425a2a0a536.zip
Merge pull request #5242 from drbaggy/master
Notes
-rw-r--r--challenge-139/james-smith/README.md10
-rw-r--r--challenge-139/james-smith/perl/ch-2.pl42
2 files changed, 45 insertions, 7 deletions
diff --git a/challenge-139/james-smith/README.md b/challenge-139/james-smith/README.md
index b1e418d85e..12cbf5c99d 100644
--- a/challenge-139/james-smith/README.md
+++ b/challenge-139/james-smith/README.md
@@ -26,7 +26,7 @@ This challenge is relatively easy - to see if the list of numbers if monotonical
* Otherwise we set previous number `$p` to the current number and continue
* If we get to the end of the list then the list is sorted and we return `1`.
-```
+```perl
sub in_order {
my $p = shift;
($p>$_) ? (return 0) : ($p=$_) for @_;
@@ -38,7 +38,7 @@ sub in_order {
* We can rewrite the `if( $x ) { y } else { z }` and `($x) ? (y) : (z)`. Why is this useful - well we can then use the brace less postfix `for` for the loop rather than having to use braces. This means the loop becomes 1 line, rather than the longer 7 line version using K&R braces. If you don't cuddle your braces it is even longer!
-```
+```perl
for (@_) {
if( $p>$_ ) {
return 0;
@@ -50,7 +50,7 @@ sub in_order {
Admittedly there is an intermediate version... That uses the exit early approach..
-```
+```perl
for (@_) {
return 0 if $p>$_;
$p = $_;
@@ -74,7 +74,7 @@ Now we don't require the actual part of the number repeats which makes the funct
This gives us the function below to get the length of the recurring sequence.
-```
+```perl
sub rec_len {
my( $D, $N, $s ) = ( shift, 1, '' );
( $s, $N ) = ( $s.int($N/$D), ($N%$D).0 ) for 0 .. 2*$D;
@@ -89,7 +89,7 @@ So now we have this function we can look at computing the long primes. We know t
Therefore we loop through all the odd numbers checking to see if the number is a prime, if it is we then check for the property that the recurring sequence has `$p-1` digits.
-```
+```perl
my( $N, @primes, @long_primes ) = ( $ARGV[0]||5 );
O: for( my $p=3; @long_primes<$N; $p+=2 ) {
diff --git a/challenge-139/james-smith/perl/ch-2.pl b/challenge-139/james-smith/perl/ch-2.pl
index 8311c8a438..f431910856 100644
--- a/challenge-139/james-smith/perl/ch-2.pl
+++ b/challenge-139/james-smith/perl/ch-2.pl
@@ -6,16 +6,54 @@ use feature qw(say);
my( $N, @primes, @long_primes ) = ( $ARGV[0]||5 );
+##
+## We know 2 isn't a long prime, and also we are
+## only looking at odd numbers so we don't have
+## to worry about the special case of 2.
+##
+## Starting at the 3 we loop through the odd numbers
+## Looking to see if the number is composite {has
+## at least 1 prime factor lower than $p}.
+##
+## Skip to next number if it is (line 2)
+##
+## If it has the long_prime property we add it
+## to the list of long primes (line 3)
+## We also add it to the primes list (line 4)
+##
+## We exit the loop when we have the appropriate
+## number of long primes
+##
+
O: for( my $p=3; @long_primes<$N; $p+=2 ) {
($p % $_) || (next O) for @primes;
push @long_primes, $p if $p - rec_len($p) == 1;
push @primes, $p;
}
+
+##
+## Output the long primes
+##
+
say $_ for @long_primes;
+##
+## We use long division here to compute the reciprocal
+## of $D, to ensure we get a repeating pattern - we
+## compute the 2$D + length $D digits as the repeating
+## pattern will comprise of a number of 0s followed by
+## the repeating pattern (which has to be at least
+## 2$D-2 long.
+##
+## This division is done in line 2.
+##
+## The 3rd line finds the shortest repeating sequence
+## tied to the end of this string, and returns its
+## length
+##
sub rec_len {
my( $D, $N, $s ) = ( shift, 1, '' );
- ($s,$N) = ( $s.int($N/$D), ($N%$D).0 ) for 0 .. 2*$D;
- $s =~ /(\d+?)\1+$/ ? length $1 : 0;
+ $s.=int($N/$D),$N%=$D,$N.=0 for 0..2*$D+length $D;
+ $s =~ /(.+?)\1+$/ ? length $1 : 0;
}