diff options
| author | Daniel Mantovani <daniel@gmail.com> | 2019-07-06 19:24:47 -0300 |
|---|---|---|
| committer | Daniel Mantovani <daniel@gmail.com> | 2019-07-06 19:24:47 -0300 |
| commit | 2874cf835f00efb80cffdca580b27828af5332dc (patch) | |
| tree | 0c17a7ecdcda4cf84bbd59b7e124c80498836f03 | |
| parent | c2a731e093f2191c2b34ab281dcd76fdcea88369 (diff) | |
| download | perlweeklychallenge-club-2874cf835f00efb80cffdca580b27828af5332dc.tar.gz perlweeklychallenge-club-2874cf835f00efb80cffdca580b27828af5332dc.tar.bz2 perlweeklychallenge-club-2874cf835f00efb80cffdca580b27828af5332dc.zip | |
my proposed solutions for challenge-015, p5 1 & 2
| -rw-r--r-- | challenge-015/daniel-mantovani/perl5/ch-1.pl | 54 | ||||
| -rw-r--r-- | challenge-015/daniel-mantovani/perl5/ch-2.pl | 63 |
2 files changed, 117 insertions, 0 deletions
diff --git a/challenge-015/daniel-mantovani/perl5/ch-1.pl b/challenge-015/daniel-mantovani/perl5/ch-1.pl new file mode 100644 index 0000000000..5e1e27fdf2 --- /dev/null +++ b/challenge-015/daniel-mantovani/perl5/ch-1.pl @@ -0,0 +1,54 @@ +# 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 v5.10; + +# we sart by using the same prime test used to solve challenge 12 - 1 +# (the regexp prime tester) +# + +sub is_prime { + return ( 7 x shift ) !~ /^(77+)\1+$/; +} + +# we will allow changing the size of the lists, and use 10 as the default +my $list_length = shift // 10; # + +# we define array for all primes, populating with the first two, +# so for n=2, p(n-1) would be 2, p(n) is 3, and p(n+1) is yet +# to be calculated + +my @primes = ( 2, 3 ); + +# we also define arrays for strong and weak primes +my ( @strong, @weak ); + +# we will loop until we get at least required amount for both strong and weak primes +while ( @strong < $list_length || @weak < 10 ) { + my $p_n = $primes[-1]; # this is p(n) + my $p_nmm = $primes[-2]; # this is p(n-1) + my $p_npp = $p_n + 1; # and we will calculate p(n+1) + + # get next prime + $p_npp++ while !is_prime($p_npp); + push @primes, $p_npp; + my $check = ( $p_nmm + $p_npp ) / 2; + push @strong, $p_n if $p_n > $check; + push @weak, $p_n if $p_n < $check; +} + +# now we just print results +say "First $list_length strong primes: " . join ', ', @strong; +say "First $list_length weak primes: " . join ', ', @weak; diff --git a/challenge-015/daniel-mantovani/perl5/ch-2.pl b/challenge-015/daniel-mantovani/perl5/ch-2.pl new file mode 100644 index 0000000000..cfdd61d66b --- /dev/null +++ b/challenge-015/daniel-mantovani/perl5/ch-2.pl @@ -0,0 +1,63 @@ +# 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 v5.10; + +# Vigenère cipher works only with ascii uppercase letters, no +# spaces, control chars, etc +# + +# we will receive 3 arguments, a direction that could be E for encrypt +# or D for decript, a keyword and the string to encode / decode: + +my ( $dir, $key, $string ) = @ARGV[ 0 .. 2 ]; + +die +"Usage: $0 <E/D> <keyword> <string>\nwith both keyword and string a sequence of uppercase plain english letters" + unless $dir + && $dir =~ /^(e|d)$/i + && $key + && $key =~ /^([A-Z])+$/ + && $string + && $string =~ /^([A-Z])+$/; + +# we start by defining two arrays, for the keyword and the text +# the arrays will have integers from 0 to 25, representing upper +# case letters from A to Z + +my @keyword = map { ord($_) - 65 } split '', $key; +my @text = map { ord($_) - 65 } split '', $string; + +# we should repeat keyword letters until we match text size, but +# we are not gonna do that, we just use module arithmetic to get +# the same effect, using keyword length as the module + +my @result; + +# encrypting is just adding text and keyword values, and +# decrypting would be the opposite, just substract keyword +# values from text +# so we define a sign variable to take care of that + +my $sign = 1; # encryption case +$sign = -1 if $dir =~ /d/i; + +# now we do encryption or decryption letter by letter +for my $i ( 0 .. $#text ) { + $result[$i] = $text[$i] + $sign * $keyword[ $i % @keyword ]; +} + +# and now we just print the result, after reconverting it +# to letters one by one + +say join( '', map { chr( ( $_ % 26 ) + 65 ) } @result ); + +# example usage (examples from wikipedia page): +# ✘ $> perl ch-2.pl E LEMON ATTACKATDAWN +# LXFOPVEFRNHR +# $> perl ch-2.pl D LEMON LXFOPVEFRNHR +# ATTACKATDAWN +# $> |
