aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrbaggy <js5@sanger.ac.uk>2021-11-16 07:10:11 +0000
committerdrbaggy <js5@sanger.ac.uk>2021-11-16 07:10:11 +0000
commit61b0eefa32e40d06de6dd0ab71c5079b9c9c5b6d (patch)
tree212882b150d30d6ae83c76ca1bf8e116337c448d
parent539750d62489e789280ec4d15a528f353e0c3baf (diff)
downloadperlweeklychallenge-club-61b0eefa32e40d06de6dd0ab71c5079b9c9c5b6d.tar.gz
perlweeklychallenge-club-61b0eefa32e40d06de6dd0ab71c5079b9c9c5b6d.tar.bz2
perlweeklychallenge-club-61b0eefa32e40d06de6dd0ab71c5079b9c9c5b6d.zip
sol to 139
-rw-r--r--challenge-139/james-smith/README.md88
-rw-r--r--challenge-139/james-smith/blog.txt1
-rw-r--r--challenge-139/james-smith/perl/ch-1.pl25
-rw-r--r--challenge-139/james-smith/perl/ch-2.pl25
4 files changed, 57 insertions, 82 deletions
diff --git a/challenge-139/james-smith/README.md b/challenge-139/james-smith/README.md
index fa191ce639..ae4b2357ff 100644
--- a/challenge-139/james-smith/README.md
+++ b/challenge-139/james-smith/README.md
@@ -1,4 +1,4 @@
-# Perl Weekly Challenge #138
+# Perl Weekly Challenge #139
You can find more information about this weeks, and previous weeks challenges at:
@@ -10,93 +10,17 @@ submit solutions in whichever language you feel comfortable with.
You can find the solutions here on github at:
-https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-138/james-smith/perl
+https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-139/james-smith/perl
-# Task 1 - Workdays
+# Task 1 - JortSort
-***Write a script to calculate the total number of workdays in the given year. (Monday to Friday)
-
-## Notes
-
-There are either 260, 261, 262 workdays in a calendar year.
-
-* In a normal year there is 261 workdays unless the year both starts and finishes on a weekend (i.e. there are 260 workdays if the year starts on a Saturday or Sunday);
-* In a leap year there is only 260 working days if Jan 1st is a Saturday & Dec 31st is a Sunday; 261 if Jan 1st is a Sunday or Dec 31st is a Saturday, 262 otherwise.
+***You are given a list of numbers. Write a script to implement JortSort. It should return true/false depending if the given list of numbers are already sorted.***
## The solution
-So we basically need 2 pieces of information given a year?
-
- * Is it a leap year
- * What is the first day of the year.
-
-We can then use a look up table which stores the number of working days (over 260) for non leap years and for leap years:
-
-| | Sun | Mon | Tue | Wed | Thu | Fri | Sat |
-| ----------------------- | --: | --: | --: | --: | --: | --: | --: |
-| **day no** | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
-| **#days non-leap year** | 0 | 1 | 1 | 1 | 1 | 1 | 0 |
-| **#days leap year** | 1 | 2 | 2 | 2 | 2 | 1 | 0 |
-
-We break this calculation into 3 functions:
-
- * `work_days` - this does the look up
- * `leap_year` - tests for leap year
- * `zellers_congruence_jan_1` - uses Zeller's congruence to work out first day of the year {works for the Gregorian calendar}
-
-All of which
-```perl
-my @EXTRA_WORKDAYS = ( [0,1,1,1,1,1,0], [1,2,2,2,2,1,0] );
-
-sub leap_year {
- $_[0]&3 || (!($_[0]%100) && $_[0]%400) ? 0 : 1;
-}
-sub zellers_congruence_jan_1 {
- ( 1 + $_[0]%100 + ($_[0]%100>>2) - ($_[0]/100<<1) + ($_[0]/400>>0) ) % 7;
-}
-
-sub work_days {
- 260 + $EXTRA_WORKDAYS[ leap_year $_[0] ][ zellers_congruence_jan_1 $_[0] - 1 ];
-}
+# Task 2 - Long Primes
-```
-
-# Task 2 - Split Number
-
-***You are given a perfect square, Write a script to figure out if the square root the given number is same as sum of 2 or more splits of the given number.***
+***Write a script to generate first 5 Long Primes. A prime number `p` is called Long Prime if `1/p` has an infinite decimal expansion repeating every `p-1` digits.***
## Solution
-We use recursion to simplify the problem - first we note that for the sqrt to be the sum of splits of the number then there are always 2 sums except in two trivial cases 0 & 1 (`n^2 = n`) so we can check this in the first wrapper function.
-
-As the first stage in the loop requires some "setup" - we write a wrapper function that:
-
- * Checks for the edge case of 0/1;
- * Passes in the square root of `$n` as the total we need to compare against in the more generic `split_no` function which works out if there is a way of summing groups of digits.
-
-`split_no` does all the hard work.
-
-It takes 2 parameters - the sum required add a string of digits. We call the function recursively
-
- * If the the string of digits is empty we have reached the end - and check to see if the remaining sum is zero.
- * If sum is less than 0 then we return 0 - no match.
- * If not we split the string into 2 pieces in all ways possible and call the function.
- * We reduce the sum required by the first part of the string;
- * And pass the second part of the string as the string of digits.
-
-```perl
-sub check_square {
- return $_[0] <= 1 ? 0 : split_no( sqrt($_[0]), $_[0] );
-}
-
-sub split_no {
- my( $sum, $str ) = @_;
- return 0 if $sum < 0;
- return 0 if $str eq '' && $sum;
- return 1 if $str eq '';
- return 1 if grep { split_no( ($sum - substr $str,$_) , substr $str, 0, $_ ) }
- 0 .. -1 + length $str;
- return 0;
-}
-
-```
diff --git a/challenge-139/james-smith/blog.txt b/challenge-139/james-smith/blog.txt
new file mode 100644
index 0000000000..6a2d58b005
--- /dev/null
+++ b/challenge-139/james-smith/blog.txt
@@ -0,0 +1 @@
+https://github.com/drbaggy/perlweeklychallenge-club/new/master/challenge-139/james-smith
diff --git a/challenge-139/james-smith/perl/ch-1.pl b/challenge-139/james-smith/perl/ch-1.pl
new file mode 100644
index 0000000000..2a4f349ec4
--- /dev/null
+++ b/challenge-139/james-smith/perl/ch-1.pl
@@ -0,0 +1,25 @@
+#!/usr/local/bin/perl
+
+use strict;
+
+use warnings;
+use feature qw(say);
+use Test::More;
+use Benchmark qw(cmpthese timethis);
+use Data::Dumper qw(Dumper);
+
+my @TESTS = (
+ [ [1..5], 1 ],
+ [ [1,3,2,4,5], 0 ],
+);
+
+is( in_order(@{$_->[0]}), $_->[1] ) foreach @TESTS;
+
+done_testing();
+
+sub in_order {
+ my $p = shift;
+ ($p>$_) ? (return 0) : ($p=$_) foreach @_;
+ return 1;
+}
+
diff --git a/challenge-139/james-smith/perl/ch-2.pl b/challenge-139/james-smith/perl/ch-2.pl
new file mode 100644
index 0000000000..5f3150a086
--- /dev/null
+++ b/challenge-139/james-smith/perl/ch-2.pl
@@ -0,0 +1,25 @@
+#!/usr/local/bin/perl
+
+use strict;
+
+use warnings;
+use feature qw(say);
+
+my( $N, $p, @primes, @long_primes ) =
+ ( @ARGV ? $ARGV[0] : 5, 1, 2 );
+
+O: while( (@long_primes < $N) && ($p += 2) ) {
+ ($p % $_) || (next O) for @primes; ## next if not prime...
+ push @long_primes, $p if $p - rec_len($p) == 1;
+ push @primes, $p;
+}
+
+say $_ for @long_primes;
+
+sub rec_len {
+ my( $D, $N, $s ) = ( shift, 1, '' );
+ ($s,$N) = $D>$N ? ($s.0, $N.0)
+ : ($s.int($N/$D),($N%$D).0) for 0 .. 2*$D;
+ $s =~ m{(\d+?)\1+$};
+ length $1;
+}