diff options
| author | Paulo Custodio <pauloscustodio@gmail.com> | 2021-01-14 22:38:22 +0000 |
|---|---|---|
| committer | Paulo Custodio <pauloscustodio@gmail.com> | 2021-01-14 22:38:22 +0000 |
| commit | 345fe4a409942b9d03cb8c9e5353a717bae7c34c (patch) | |
| tree | b0b7512dbbbed60b51acda511dfca3666e2ba20a | |
| parent | cebbd79c18a3d0716dbbabc0d696c1df5994039a (diff) | |
| download | perlweeklychallenge-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/README | 1 | ||||
| -rw-r--r-- | challenge-015/paulo-custodio/perl/ch-1.pl | 50 | ||||
| -rw-r--r-- | challenge-015/paulo-custodio/perl/ch-2.pl | 63 | ||||
| -rw-r--r-- | challenge-015/paulo-custodio/test.pl | 30 |
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; +} |
