aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordcw <d.white@imperial.ac.uk>2019-06-23 17:30:34 +0100
committerdcw <d.white@imperial.ac.uk>2019-06-23 17:30:34 +0100
commit4ace91a773b650e647b7b9db66831009bf5e1b73 (patch)
treeb266720144fd446430cd6976b658d682e02c408e
parente1f29f2917a8494374a5fe97606391107bacd24a (diff)
downloadperlweeklychallenge-club-4ace91a773b650e647b7b9db66831009bf5e1b73.tar.gz
perlweeklychallenge-club-4ace91a773b650e647b7b9db66831009bf5e1b73.tar.bz2
perlweeklychallenge-club-4ace91a773b650e647b7b9db66831009bf5e1b73.zip
Did the challenges starting at 1700 on Sunday 23rd. got them both working by 1730..
-rw-r--r--challenge-013/duncan-c-white/README61
-rwxr-xr-xchallenge-013/duncan-c-white/perl5/ch-1.pl56
-rwxr-xr-xchallenge-013/duncan-c-white/perl5/ch-2.pl68
3 files changed, 154 insertions, 31 deletions
diff --git a/challenge-013/duncan-c-white/README b/challenge-013/duncan-c-white/README
index 3235e656a6..818ecf50b2 100644
--- a/challenge-013/duncan-c-white/README
+++ b/challenge-013/duncan-c-white/README
@@ -1,40 +1,39 @@
-Challenge 1: "The numbers formed by adding one to the products of the
-smallest primes are called the Euclid Numbers. Write a script that finds
-the smallest Euclid Number that is not prime."
+Challenge 1: "Write a script to print the date of last Friday of every
+month of a given year. For example, if the given year is 2019 then it
+should print the following:
+
+2019/01/25
+2019/02/22
+2019/03/29
+2019/04/26
+2019/05/31
+2019/06/28
+2019/07/26
+2019/08/30
+2019/09/27
+2019/10/25
+2019/11/29
+2019/12/27
-My notes:
-
-From the wiki:
-
-primes are 2, 3, 5, 7, 11, 13..
-products are 2, 6, 30, 210, 2310, 30030...
-and Euclid numbers are 3, 7, 31, 211, 2301, 30031...
-btw, the Wiki page gives the answer:
- E(6)=30031 is first composite Euclid number (59x509)
+My notes:
-Euclid numbers will grow like factorials, being products, will we need
-to use bigint? 30031 being the answer suggests not:-). I already have a
-"mkprimes.c" program to generate first N primes, so let's use that, hence
-our Perl code will simply use an of primes (rather than generating the primes
-ourselves). Just need isprime(n) type function checking i=2..sqrt(n). Simple!
+Date::Manip should be able to do that easily enough.
-Challenge 2: "Write a script that finds the common directory path,
-given a collection of paths and directory separator. For example, if
-the following paths are supplied.
+Challenge 2: Write a script to demonstrate Mutually Recursive methods. Two
+methods are mutually recursive if the first method calls the second and
+the second calls first in turn. Using the mutually recursive methods,
+generate Hofstadter Female and Male sequences.
- /a/b/c/d
- /a/b/cd
- /a/b/cc
- /a/b/c/d/e
+ F ( 0 ) = 1 ; M ( 0 ) = 0
+ F ( n ) = n - M ( F ( n - 1 ) ) , n > 0
+ M ( n ) = n - F ( M ( n - 1 ) ) , n > 0."
-and the path separator is /. Your script should return /a/b as common
-directory path."
-My notes:
+ My notes:
-The obvious approach is: split each path on pathsep into an array of segments,
-eg. /a/b/c/d == (a,b,c,d) note no '' before first element a
-then compare do all paths have "a" in their segment 0? if so, prefix += "/a"
-etc. make sure we return "/" if the initial segments are not all identical.
+ Ok, looks straight forward enough, and I always liked Douglas Hofstadter
+ and especially his book Godel, Esher and Bach. Initially, I did it as
+ straightforward mutually recursive functions, but then I added Memoize
+ optimization when I realized how slow it gets as N increases (eg to 80..)..
diff --git a/challenge-013/duncan-c-white/perl5/ch-1.pl b/challenge-013/duncan-c-white/perl5/ch-1.pl
new file mode 100755
index 0000000000..221b7892d1
--- /dev/null
+++ b/challenge-013/duncan-c-white/perl5/ch-1.pl
@@ -0,0 +1,56 @@
+#!/usr/bin/perl
+
+# Challenge 1: "Write a script to print the date of last Friday of every
+# month of a given year. For example, if the given year is 2019 then it
+# should print the following:
+#
+# 2019/01/25
+# 2019/02/22
+# 2019/03/29
+# 2019/04/26
+# 2019/05/31
+# 2019/06/28
+# 2019/07/26
+# 2019/08/30
+# 2019/09/27
+# 2019/10/25
+# 2019/11/29
+# 2019/12/27
+#
+#
+# My notes:
+#
+# Date::Manip should be able to do that easily enough.
+
+use strict;
+use warnings;
+use Function::Parameters;
+use Date::Manip;
+use Data::Dumper;
+
+die "Usage: ch-1.pl YEAR\n" unless @ARGV==1;
+my $year = shift;
+
+#
+# my $dayno = findlasstfriday( $year, $month );
+# Find the day number (1..31) of the last Friday in
+# month $month (1..12) in year $year.
+#
+fun findlasstfriday( $year, $month )
+{
+ my $ndays = Date_DaysInMonth $month,$year;
+ my $lastfriday = -1;
+ foreach my $dayno (21..$ndays)
+ {
+ my $day = Date_DayOfWeek( $month, $dayno, $year );
+ $lastfriday = $dayno if $day == 5;
+ }
+ return $lastfriday;
+}
+
+
+foreach my $m (1..12)
+{
+ my $dayno = findlasstfriday( $year, $m );
+ printf "$year/%02d/$dayno\n", $m;
+}
diff --git a/challenge-013/duncan-c-white/perl5/ch-2.pl b/challenge-013/duncan-c-white/perl5/ch-2.pl
new file mode 100755
index 0000000000..650848e922
--- /dev/null
+++ b/challenge-013/duncan-c-white/perl5/ch-2.pl
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+
+# Challenge 2: Write a script to demonstrate Mutually Recursive methods. Two
+# methods are mutually recursive if the first method calls the second and
+# the second calls first in turn. Using the mutually recursive methods,
+# generate Hofstadter Female and Male sequences.
+#
+# F ( 0 ) = 1 ; M ( 0 ) = 0
+# F ( n ) = n - M ( F ( n - 1 ) ) , n > 0
+# M ( n ) = n - F ( M ( n - 1 ) ) , n > 0."
+#
+# My notes:
+
+# Ok, looks straight forward enough, and I always liked Douglas Hofstadter
+# and especially his book Godel, Esher and Bach. Initially, I did it as
+# straightforward mutually recursive functions, but then I added Memoize
+# optimization when I realized how slow it gets as N increases (eg to 80..)..
+
+use strict;
+use warnings;
+use Function::Parameters;
+use Memoize;
+use Data::Dumper;
+
+#
+# my $value = male( $n );
+# Generate and return the value of Hofstdter's male sequence for $n.
+# rules:
+# F ( 0 ) = 1 ; M ( 0 ) = 0
+# F ( n ) = n - M ( F ( n - 1 ) ) , n > 0
+# M ( n ) = n - F ( M ( n - 1 ) ) , n > 0."
+#
+fun male( $n )
+{
+ die "male( $n ): n must be >= 0\n" unless $n>=0;
+ return 0 if $n==0;
+ return $n - female( male( $n-1 ) );
+}
+
+
+#
+# my $value = female( $n );
+# Generate and return the value of Hofstdter's female sequence for $n.
+# rules:
+# F ( 0 ) = 1 ; M ( 0 ) = 0
+# F ( n ) = n - M ( F ( n - 1 ) ) , n > 0
+# M ( n ) = n - F ( M ( n - 1 ) ) , n > 0."
+#
+fun female( $n )
+{
+ die "female( $n ): n must be >= 0\n" unless $n>=0;
+ return 1 if $n==0;
+ return $n - male( female( $n-1 ) );
+}
+
+
+memoize( 'male' );
+memoize( 'female' );
+
+die "Usage: ch-2.pl maxN\n" unless @ARGV==1;
+my $maxn = shift;
+
+foreach my $n (0..$maxn)
+{
+ my $mv = male( $n );
+ my $fv = female( $n );
+ print "male($n) = $mv, female($n) = $fv\n";
+}