aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Custodio <pauloscustodio@gmail.com>2021-01-14 22:38:22 +0000
committerPaulo Custodio <pauloscustodio@gmail.com>2021-01-14 22:38:22 +0000
commit345fe4a409942b9d03cb8c9e5353a717bae7c34c (patch)
treeb0b7512dbbbed60b51acda511dfca3666e2ba20a
parentcebbd79c18a3d0716dbbabc0d696c1df5994039a (diff)
downloadperlweeklychallenge-club-345fe4a409942b9d03cb8c9e5353a717bae7c34c.tar.gz
perlweeklychallenge-club-345fe4a409942b9d03cb8c9e5353a717bae7c34c.tar.bz2
perlweeklychallenge-club-345fe4a409942b9d03cb8c9e5353a717bae7c34c.zip
Add Perl solution to challenge 015
-rw-r--r--challenge-015/paulo-custodio/README1
-rw-r--r--challenge-015/paulo-custodio/perl/ch-1.pl50
-rw-r--r--challenge-015/paulo-custodio/perl/ch-2.pl63
-rw-r--r--challenge-015/paulo-custodio/test.pl30
4 files changed, 144 insertions, 0 deletions
diff --git a/challenge-015/paulo-custodio/README b/challenge-015/paulo-custodio/README
new file mode 100644
index 0000000000..87dc0b2fbd
--- /dev/null
+++ b/challenge-015/paulo-custodio/README
@@ -0,0 +1 @@
+Solution by Paulo Custodio
diff --git a/challenge-015/paulo-custodio/perl/ch-1.pl b/challenge-015/paulo-custodio/perl/ch-1.pl
new file mode 100644
index 0000000000..655124d8bb
--- /dev/null
+++ b/challenge-015/paulo-custodio/perl/ch-1.pl
@@ -0,0 +1,50 @@
+#!/usr/bin/perl
+
+# Challenge 015
+#
+# Task #1
+# Write a script to generate first 10 strong and weak prime numbers.
+#
+# For example, 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
+
+use strict;
+use warnings;
+use 5.030;
+use Math::Prime::Util 'next_prime';
+
+sub prime_iter {
+ my($strong) = @_;
+ my @primes = (1,2,3); # 1 + first two primes; 1 is discarded on first iteration
+ return sub {
+ while (1) {
+ # get next prime, drop oldest
+ shift @primes;
+ push @primes, next_prime($primes[-1]);
+
+ my $avg = ($primes[-3]+$primes[-1])/2;
+ if ($strong) {
+ return $primes[-2] if $primes[-2] > $avg;
+ }
+ else {
+ return $primes[-2] if $primes[-2] < $avg;
+ }
+ }
+ };
+}
+
+my $N = shift || 10;
+
+my $iter = prime_iter(1);
+say "Strong Prime: ", join(", ", map {$iter->()} 1..$N);
+
+$iter = prime_iter(0);
+say "Weak Prime: ", join(", ", map {$iter->()} 1..$N);
diff --git a/challenge-015/paulo-custodio/perl/ch-2.pl b/challenge-015/paulo-custodio/perl/ch-2.pl
new file mode 100644
index 0000000000..8147d92b83
--- /dev/null
+++ b/challenge-015/paulo-custodio/perl/ch-2.pl
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+
+# Challenge 015
+#
+# Task #2
+# Write a script to implement Vigenère cipher. The script should be able encode
+# and decode. Checkout wiki page for more information.
+
+use strict;
+use warnings;
+use 5.030;
+
+my($op, $key, @text) = @ARGV;
+if ($op && $op =~ /^enc/i) {
+ say encode("@text", $key);
+}
+elsif ($op && $op =~ /^dec/i) {
+ say decode("@text", $key);
+}
+else {
+ die "Usage: ch-2.pl encode|decode key text\n";
+}
+
+
+sub text_codes {
+ my($text) = @_;
+ $text = uc($text);
+ $text =~ s/\W//g;
+ my @codes = map {ord($_)-ord('A')} split //, $text;
+ return @codes;
+}
+
+sub codes_text {
+ my(@codes) = @_;
+ return join '', map {chr($_+ord('A'))} @codes;
+}
+
+sub encode {
+ my($plain, $key) = @_;
+ return vigenere($plain, $key, 1);
+}
+
+sub decode {
+ my($plain, $key) = @_;
+ return vigenere($plain, $key, 0);
+}
+
+sub vigenere {
+ my($plain, $key, $encode) = @_;
+ my @key = text_codes($key);
+ my @plain = text_codes($plain);
+ my @cipher;
+ for my $pc (@plain) {
+ if ($encode) {
+ push @cipher, ($pc + $key[0]) % 26;
+ }
+ else {
+ push @cipher, ($pc - $key[0] + 26) % 26;
+ }
+ push @key, shift @key; # rotate key
+ }
+ return codes_text(@cipher);
+}
diff --git a/challenge-015/paulo-custodio/test.pl b/challenge-015/paulo-custodio/test.pl
new file mode 100644
index 0000000000..986b6afb13
--- /dev/null
+++ b/challenge-015/paulo-custodio/test.pl
@@ -0,0 +1,30 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Test::More;
+use 5.030;
+
+is capture("perl perl/ch-1.pl"), <<END;
+Strong Prime: 11, 17, 29, 37, 41, 59, 67, 71, 79, 97
+Weak Prime: 3, 7, 13, 19, 23, 31, 43, 47, 61, 73
+END
+
+is capture("perl perl/ch-1.pl 47"), <<END;
+Strong Prime: 11, 17, 29, 37, 41, 59, 67, 71, 79, 97, 101, 107, 127, 137, 149, 163, 179, 191, 197, 223, 227, 239, 251, 269, 277, 281, 307, 311, 331, 347, 367, 379, 397, 419, 431, 439, 457, 461, 479, 487, 499, 521, 541, 557, 569, 587, 599
+Weak Prime: 3, 7, 13, 19, 23, 31, 43, 47, 61, 73, 83, 89, 103, 109, 113, 131, 139, 151, 167, 181, 193, 199, 229, 233, 241, 271, 283, 293, 313, 317, 337, 349, 353, 359, 383, 389, 401, 409, 421, 433, 443, 449, 463, 467, 491, 503, 509
+END
+
+
+is capture("perl perl/ch-2.pl encode LEMON ATTACKATDAWN"), "LXFOPVEFRNHR\n";
+is capture("perl perl/ch-2.pl decode LEMON LXFOPVEFRNHR"), "ATTACKATDAWN\n";
+
+
+done_testing;
+
+sub capture {
+ my($cmd) = @_;
+ my $out = `$cmd`;
+ $out =~ s/[ \t\v\f\r]*\n/\n/g;
+ return $out;
+}