aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordcw <d.white@imperial.ac.uk>2019-07-07 21:17:38 +0100
committerdcw <d.white@imperial.ac.uk>2019-07-07 21:17:38 +0100
commit5df1901d7acf7a9db09159cd66e29221a0e73293 (patch)
tree12f8abefcc2e8a6e07ec2f524963b064c1fbc26a
parent3c2e164e9771e96e943684a449968c050de0b9f6 (diff)
downloadperlweeklychallenge-club-5df1901d7acf7a9db09159cd66e29221a0e73293.tar.gz
perlweeklychallenge-club-5df1901d7acf7a9db09159cd66e29221a0e73293.tar.bz2
perlweeklychallenge-club-5df1901d7acf7a9db09159cd66e29221a0e73293.zip
added my solutions to this week's challenge
-rw-r--r--challenge-015/duncan-c-white/README39
-rwxr-xr-xchallenge-015/duncan-c-white/perl5/ch-1.pl101
-rwxr-xr-xchallenge-015/duncan-c-white/perl5/ch-2.pl82
3 files changed, 196 insertions, 26 deletions
diff --git a/challenge-015/duncan-c-white/README b/challenge-015/duncan-c-white/README
index 38610de25a..3127812a2c 100644
--- a/challenge-015/duncan-c-white/README
+++ b/challenge-015/duncan-c-white/README
@@ -1,39 +1,26 @@
-Challenge 1: "Write a script to generate Van Eck's sequence
-starting with 0. Van Eck's sequence is defined by:
+Challenge 1: "Write a script to generate first 10 strong and weak prime numbers.
-Let a0 = 0. Then, for n >= 0, if there exists an m < n such that am =
-an, take the largest such m and set an+1 = n - m; otherwise an+1 = 0.
+the nth prime number is represented by p(n).
-Thus the first occurrence of an integer in the sequence is followed by
-a 0, and the second and subsequent occurrences are followed by the size
-of the gap between the two most recent occurrences.
+ p(1) = 2
+ p(2) = 3
+ p(3) = 5
+ p(4) = 7
+ p(5) = 11
-The sequence is named after Jan Ritsema van Eck, who submitted it to
-the On-Line Encyclopedia of Integer Sequences.
-
-The first few terms of the sequence are(OEIS: A181391):
-
- 0, 0, 1, 0, 2, 0, 2, 2, 1, 6, 0, 5, 0, 2, 6, 5, 4, 0, 5..
+ Strong Prime number p(n) when p(n) > [ p(n-1) + p(n+1) ] / 2
+ Weak Prime number p(n) when p(n) < [ p(n-1) + p(n+1) ] / 2
"
My notes:
-Sounds easy enough (and not, in fact, obviously recursive).
+Sounds easy enough.
-Challenge 2: "Using only the official postal (2-letter) abbreviations
-for the 50 U.S. states, write a script to find the longest English word
-you can spell? Here is the list of U.S. states abbreviations as per
-wikipedia page. This challenge was proposed by team member Neil Bowers.
-
-For example,
-Pennsylvania + Connecticut = PACT
-Wisconsin + North Dakota = WIND
-Maine + Alabama = MEAL
-California + Louisiana + Massachusetts + Rhode Island = Calamari
-"
+Challenge 2: "Write a script to implement the Vigenère cipher. The script
+should be able to encode and decode."
My notes:
-Ok, looks like an interesting search problem.
+Ok, pretty easy.
diff --git a/challenge-015/duncan-c-white/perl5/ch-1.pl b/challenge-015/duncan-c-white/perl5/ch-1.pl
new file mode 100755
index 0000000000..a2a9fe704f
--- /dev/null
+++ b/challenge-015/duncan-c-white/perl5/ch-1.pl
@@ -0,0 +1,101 @@
+#!/usr/bin/perl
+
+# Challenge 1: "Write a script to generate first 10 strong and weak prime numbers.
+#
+# the nth prime number is represented by p(n).
+#
+# p(1) = 2
+# p(2) = 3
+# p(3) = 5
+# p(4) = 7
+# p(5) = 11
+#
+# Strong Prime number p(n) when p(n) > [ p(n-1) + p(n+1) ] / 2
+# Weak Prime number p(n) when p(n) < [ p(n-1) + p(n+1) ] / 2
+# "
+#
+# My notes:
+#
+# Sounds easy enough.
+
+use strict;
+use warnings;
+use Function::Parameters;
+use Data::Dumper;
+
+#
+# my @prime = make_primes( $n );
+# calculate all primes up to $n (nb: in this sense,
+# 1 is not a prime, so $prime[0] == 2)
+#
+fun make_primes( $n )
+{
+ my @isprime;
+ for( my $i=1; $i<=$n; $i++ )
+ {
+ $isprime[$i] = 1; # initially
+ }
+
+ my $upper = int(sqrt($n));
+ #print "debug: n=$n, upper=$upper\n";
+ for( my $i=2; $i<=$upper; $i++ )
+ {
+ if( $isprime[$i] )
+ {
+ #print "debug: crossing out multiples of $i\n";
+ for( my $j=$i*$i; $j<=$n; $j+=$i )
+ {
+ $isprime[$j] = 0;
+ }
+ }
+ }
+
+ my @prime;
+ for( my $i=2; $i<=$n; $i++ )
+ {
+ push @prime, $i if $isprime[$i];
+ }
+ return @prime;
+}
+
+
+
+die "Usage: ch-1.pl N\n" unless @ARGV==1;
+my $n = shift;
+
+my @prime = make_primes( 200 * $n ); # 200 is a guess:-)
+
+my @strong;
+my @weak;
+my @neither = (2);
+
+foreach my $i (1..@prime-2)
+{
+ my $pi = $prime[$i];
+ my $pimo = $prime[$i-1];
+ my $pipo = $prime[$i+1];
+ my $avg = ($pimo + $pipo)/2;
+ # Strong Prime number p(n) when p(n) > [ p(n-1) + p(n+1) ] / 2
+ if( $pi > $avg && @strong < $n )
+ {
+ push @strong, $pi;
+ }
+ # Weak Prime number p(n) when p(n) < [ p(n-1) + p(n+1) ] / 2
+ if( $pi < $avg && @weak < $n )
+ {
+ push @weak, $pi;
+ }
+ # Neither Prime number p(n) when p(n) == [ p(n-1) + p(n+1) ] / 2
+ if( $pi == $avg && @neither < $n )
+ {
+ push @neither, $pi;
+ }
+}
+
+print "first $n strong primes: ", join(',',@strong), "\n";
+print "first $n weak primes: ", join(',',@weak), "\n";
+print "first $n neither strong-nor-weak primes: ", join(',',@neither), "\n";
+
+die "need more strong primes (have ", scalar(@strong), ")\n" if @strong<$n;
+die "need more weak primes (have ", scalar(@weak), ")\n" if @weak<$n;
+die "need more neither primes (have ", scalar(@neither), ")\n" if @neither<$n;
diff --git a/challenge-015/duncan-c-white/perl5/ch-2.pl b/challenge-015/duncan-c-white/perl5/ch-2.pl
new file mode 100755
index 0000000000..48e6b3e67a
--- /dev/null
+++ b/challenge-015/duncan-c-white/perl5/ch-2.pl
@@ -0,0 +1,82 @@
+#!/usr/bin/perl
+
+# Challenge 2: "Write a script to implement the Vigenère cipher. The script
+# should be able to encode and decode."
+#
+# My notes:
+#
+# Ok, pretty easy.
+
+use strict;
+use warnings;
+use Function::Parameters;
+use Data::Dumper;
+use Getopt::Long;
+
+my $territories = 0;
+die "Usage: ch-2.pl [encrypt|decrypt] TEXT KEY\n" unless
+ @ARGV == 3;
+
+my $mode = shift;
+my $text = shift;
+my $key = shift;
+
+#
+# my $ciphertext = encrypt( $plaintext, $key );
+# Encrypt the $plaintext using the $key. Return the ciphertext.
+#
+fun encrypt( $plaintext, $key )
+{
+ my $a = ord('A');
+ my $result = "";
+ $key = uc($key);
+ $plaintext = uc($plaintext);
+ my @k = split(//, $key );
+ my @runningkey = @k;
+ foreach my $letter (split( //, $plaintext))
+ {
+ next unless $letter =~ /[A-Z]/;
+ my $keyletter = shift @runningkey;
+ push @runningkey, @k unless @runningkey;
+ my $n = (ord($letter) - $a + ord($keyletter) - $a) % 26;
+ $result .= chr($n+$a);
+ }
+ return $result;
+}
+
+
+#
+# my $plaintext = decrypt( $cipherrtext, $key );
+# Decrypt the $ciphertext using the $key. Return the plain text.
+#
+fun decrypt( $ciphertext, $key )
+{
+ my $a = ord('A');
+ my $result = "";
+ $key = uc($key);
+ $ciphertext = uc($ciphertext);
+ my @k = split(//, $key );
+ my @runningkey = @k;
+ foreach my $letter (split( //, $ciphertext))
+ {
+ next unless $letter =~ /[A-Z]/;
+ my $keyletter = shift @runningkey;
+ push @runningkey, @k unless @runningkey;
+ my $n = (ord($letter) - $a - (ord($keyletter) - $a)) % 26;
+ $result .= chr($n+$a);
+ }
+ return $result;
+}
+
+
+my $out;
+if( $mode =~ /^e/i )
+{
+ $out = encrypt( $text, $key );
+} else
+{
+ $out = decrypt( $text, $key );
+}
+
+print "output $out\n";
+