From e8c27fa6b55e7bdd8ea8fdaffb80df44b8efdc34 Mon Sep 17 00:00:00 2001 From: Dave Jacoby Date: Tue, 25 Jun 2019 11:07:35 -0400 Subject: I Did A Perl 6! --- challenge-014/dave-jacoby/p014c2.p6 | 54 +++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100755 challenge-014/dave-jacoby/p014c2.p6 diff --git a/challenge-014/dave-jacoby/p014c2.p6 b/challenge-014/dave-jacoby/p014c2.p6 new file mode 100755 index 0000000000..84a9bd0117 --- /dev/null +++ b/challenge-014/dave-jacoby/p014c2.p6 @@ -0,0 +1,54 @@ +#!/usr/bin/env perl6 + +# My first Perl6 entry! + +# This took a bit. First I had to wipe and redo my rakudobrew, +# because I pull out Perl 6 once every two years or so. Looking +# at Damian Conway's Perl 6 solutions, I can't help but think this +# is "baby perl 6" (which I'm sure Larry would say is okay), but +# there's a command or two that solve everything, as long as you +# throw away decades of mental models to get there. + +# I did a qw{} in Perl 5, but I was afraid and just made the +# array myself here. + + +my %states = map { $_ => 1 } , + "AL","AK","AZ","AR","CA","CO","CT","DE","FL","GA", + "HI","ID","IL","IN","IA","KS","KY","LA","ME","MD", + "MA","MI","MN","MS","MO","MT","NE","NV","NH","NJ", + "NM","NY","NC","ND","OH","OK","OR","PA","RI","SC", + "CD","TN","TX","UT","VT","VA","WA","WV","WI","WY"; + +my @words = '/usr/share/dict/words'.IO.lines; + +# when testing, use a smaller data set +# @words = "PACT","WIND","PERL","CALAMARI"; + +my $longest = ''; +MAIN: for @words -> $word { + my @word = $word ~~ m:g/\w ** 2/; + + my $join = @word.join(''); + next if $join ne $word; + + for @word -> $wo { + my $n = %states{$wo.uc} ?? 1 !! 0; + next MAIN unless $n; + } + + $longest = $word if $longest.chars < $word.chars; + } + +say $longest; + +# the word-list I have here is smaller than the one I have on my +# laptop, so the longest word I have is "Concorde", being +# Colorado +# North Carolina +# Oregon +# Delaware + +# but my Perl 5 version gets the same, so ¯\_(ツ)_/¯ + +# I am disappointed by the speed drop, tho \ No newline at end of file -- cgit From 92d8c7c1e0270d95f7b1334bdf5e736a2a468c91 Mon Sep 17 00:00:00 2001 From: Dave Jacoby Date: Tue, 25 Jun 2019 11:09:51 -0400 Subject: Revert "I Did A Perl 6!" This reverts commit e8c27fa6b55e7bdd8ea8fdaffb80df44b8efdc34. --- challenge-014/dave-jacoby/p014c2.p6 | 54 ------------------------------------- 1 file changed, 54 deletions(-) delete mode 100755 challenge-014/dave-jacoby/p014c2.p6 diff --git a/challenge-014/dave-jacoby/p014c2.p6 b/challenge-014/dave-jacoby/p014c2.p6 deleted file mode 100755 index 84a9bd0117..0000000000 --- a/challenge-014/dave-jacoby/p014c2.p6 +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env perl6 - -# My first Perl6 entry! - -# This took a bit. First I had to wipe and redo my rakudobrew, -# because I pull out Perl 6 once every two years or so. Looking -# at Damian Conway's Perl 6 solutions, I can't help but think this -# is "baby perl 6" (which I'm sure Larry would say is okay), but -# there's a command or two that solve everything, as long as you -# throw away decades of mental models to get there. - -# I did a qw{} in Perl 5, but I was afraid and just made the -# array myself here. - - -my %states = map { $_ => 1 } , - "AL","AK","AZ","AR","CA","CO","CT","DE","FL","GA", - "HI","ID","IL","IN","IA","KS","KY","LA","ME","MD", - "MA","MI","MN","MS","MO","MT","NE","NV","NH","NJ", - "NM","NY","NC","ND","OH","OK","OR","PA","RI","SC", - "CD","TN","TX","UT","VT","VA","WA","WV","WI","WY"; - -my @words = '/usr/share/dict/words'.IO.lines; - -# when testing, use a smaller data set -# @words = "PACT","WIND","PERL","CALAMARI"; - -my $longest = ''; -MAIN: for @words -> $word { - my @word = $word ~~ m:g/\w ** 2/; - - my $join = @word.join(''); - next if $join ne $word; - - for @word -> $wo { - my $n = %states{$wo.uc} ?? 1 !! 0; - next MAIN unless $n; - } - - $longest = $word if $longest.chars < $word.chars; - } - -say $longest; - -# the word-list I have here is smaller than the one I have on my -# laptop, so the longest word I have is "Concorde", being -# Colorado -# North Carolina -# Oregon -# Delaware - -# but my Perl 5 version gets the same, so ¯\_(ツ)_/¯ - -# I am disappointed by the speed drop, tho \ No newline at end of file -- cgit From afda1ea26596fc46aa2c1932cbe8f52aad896fda Mon Sep 17 00:00:00 2001 From: Dave Jacoby Date: Mon, 1 Jul 2019 12:24:58 -0400 Subject: another week done --- challenge-015/dave-jacoby/perl5/ch-1.pl | 78 ++++++++++++++++++++++++ challenge-015/dave-jacoby/perl5/ch-2.pl | 101 ++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 challenge-015/dave-jacoby/perl5/ch-1.pl create mode 100644 challenge-015/dave-jacoby/perl5/ch-2.pl diff --git a/challenge-015/dave-jacoby/perl5/ch-1.pl b/challenge-015/dave-jacoby/perl5/ch-1.pl new file mode 100644 index 0000000000..4c66702a02 --- /dev/null +++ b/challenge-015/dave-jacoby/perl5/ch-1.pl @@ -0,0 +1,78 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use feature qw{ postderef say signatures state }; +no warnings qw{ experimental::postderef experimental::signatures }; + +# Write a script to generate first 10 strong and weak prime numbers. + +# https://en.wikipedia.org/wiki/Strong_prime +# (which contains a list of strong primes to ensure things are correct) + +# 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 + +my @primes; +my @strong; +my @weak; + +# create list of primes to judge strong, weak or balanced +while ( @strong < 10 && @weak < 10 ) { + state $c += 1; + if ( is_prime($c) ) { push @primes, $c } + last if scalar @primes > 100; +} + +for my $n ( 1 .. @primes ) { + my $swb = is_strong($n); + my $o = $primes[$n]; + push @strong, $o if $swb == 1; + push @weak, $o if $swb == -1; + last if @weak > 10 && @strong > 10; + say $swb; +} +say 'strong: ' . join ", ", @strong[0..9]; +say 'weak: ' . join ", ", @weak[0..9]; +exit; + +# 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 + +# 1 if strong +# -1 if weak +# 0 if balanced +sub is_strong ( $n ) { + my $o = $primes[$n]; + return 3 if $n <= 0; # no n-1 -- look up this special case + return 4 + if !$primes[ $n + 1 ]; # no n+1 -- we should be done well before then + my $p = ( $primes[ $n - 1 ] + $primes[ $n + 1 ] ) / 2; + return 1 if $o > $p; + return -1 if $o < $p; + return 0; +} + +# this one again +sub is_prime ( $n ) { + my @factors = factor($n); + return scalar @factors == 1 ? 1 : 0; +} + +# this has a slight modification, going only to sqrt $n, because +# there can't be a factor above that. Duh. +sub factor ( $n ) { + my @factors; + for my $i ( 1 .. sqrt $n ) { + push @factors, $i if $n % $i == 0; + } + return @factors; +} diff --git a/challenge-015/dave-jacoby/perl5/ch-2.pl b/challenge-015/dave-jacoby/perl5/ch-2.pl new file mode 100644 index 0000000000..5dd4ca6076 --- /dev/null +++ b/challenge-015/dave-jacoby/perl5/ch-2.pl @@ -0,0 +1,101 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use feature qw{ postderef say signatures state fc }; +no warnings qw{ experimental::postderef experimental::signatures }; + +my $keyword = 'ATTACKATDAWN'; +my $cleartext = <<'END'; +Write a script to implement Vigenere cipher. +The script should be able encode and decode. +END + +# the point ISN'T to show off Getopt or File I/O techniques +# so I'm going way simple here. +$keyword = $ARGV[0] ? $ARGV[0] : $keyword; +$cleartext = $ARGV[1] ? $ARGV[1] : $cleartext; + +$keyword =~ tr/a-z/A-Z/; +$keyword =~ s/\W//g; +$cleartext =~ tr/a-z/A-Z/; # or uc $cleartext. TMTOWTDI +$cleartext =~ s/\W//g; # text that isn't alpha isn't encrypted + # and can give the game away. + +my $cyphertext = encode_vigenere( $keyword, $cleartext ); +my $decrypt = decode_vigenere( $keyword, $cyphertext ); +say <<"END"; + CLEAR: + $cleartext + CYPHER: + $cyphertext + DECRYPT: + $decrypt +END +exit; + +sub encode_vigenere ( $keyword, $cleartext ) { + my @keyword = split m{}, $keyword; + my @base = make_core_cypher(); + my @alpha = 'A' .. 'Z'; + my %alpha = map { $alpha[$_] => $_ } 0 .. 25; + my @cypher; + for my $clear ( split m{}, $cleartext ) { + state $c = 0; + # here's where I made a mistake, and wrote my decode to + # work with my mistake. I was using $c % length $keyword + # as the column determiner, rather than the index of the + # letter at position $c % length $keyword. + # the keyword 'aaaa' should give a cyphertext that's the + # same as the cleartext. + + # If your algorithm cannot return an encrypted letter + # that's the same as the clear letter, you have an + # attack vector, but if your keyword is all "a" with this, + # you have not encrypted anything. + + # and, really, long-term viability is not helped by + # short variable names + my $k = $keyword[ $c % length $keyword ]; + my $d = $alpha{$k}; + my $e = $alpha{$clear}; + my $f = $base[$d][$e]; + push @cypher, $f; + $c++; + } + return join '', @cypher; +} + +sub decode_vigenere ( $keyword, $cyphertext ) { + my @keyword = split m{}, $keyword; + my @base = make_core_cypher(); + my @alpha = 'A' .. 'Z'; + my %alpha = map { $alpha[$_] => $_ } 0 .. 25; + my @clear; + for my $cypher ( split m{}, $cyphertext ) { + state $c = 0; + my $k = $keyword[ $c % length $keyword ]; + my $d = $alpha{$k}; + my $e; + for my $i ( 0 .. 25 ) { + $e = $i if $base[$d][$i] eq $cypher; + } + my $f = $alpha[$e]; + push @clear, $f; + $c++; + } + return join '', @clear; +} + +sub make_core_cypher () { + my @alpha = 'A' .. 'Z'; + my @output; + for my $i ( 0 .. 25 ) { + for my $j ( 0 .. 25 ) { + my $k = ( $i + $j ) % 26; + my $l = $alpha[$k]; + $output[$i][$j] = $l; + } + } + return @output; +} -- cgit From 24ccf59f0aeccc726a3c7f26c945307bd1033b72 Mon Sep 17 00:00:00 2001 From: Dave Jacoby Date: Mon, 1 Jul 2019 13:06:33 -0400 Subject: Committing from within VS Code for the first time --- challenge-015/dave-jacoby/blog.txt | 1 + challenge-015/dave-jacoby/perl5/ch-1.pl | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 challenge-015/dave-jacoby/blog.txt diff --git a/challenge-015/dave-jacoby/blog.txt b/challenge-015/dave-jacoby/blog.txt new file mode 100644 index 0000000000..b28204810f --- /dev/null +++ b/challenge-015/dave-jacoby/blog.txt @@ -0,0 +1 @@ +https://jacoby.github.io/2019/07/01/perl-weekly-challenge-015.html \ No newline at end of file diff --git a/challenge-015/dave-jacoby/perl5/ch-1.pl b/challenge-015/dave-jacoby/perl5/ch-1.pl index 4c66702a02..f1ab521cd4 100644 --- a/challenge-015/dave-jacoby/perl5/ch-1.pl +++ b/challenge-015/dave-jacoby/perl5/ch-1.pl @@ -38,7 +38,6 @@ for my $n ( 1 .. @primes ) { push @strong, $o if $swb == 1; push @weak, $o if $swb == -1; last if @weak > 10 && @strong > 10; - say $swb; } say 'strong: ' . join ", ", @strong[0..9]; say 'weak: ' . join ", ", @weak[0..9]; -- cgit