diff options
| -rw-r--r-- | challenge-162/jaldhar-h-vyas/blog.txt | 2 | ||||
| -rwxr-xr-x | challenge-162/jaldhar-h-vyas/perl/ch-2.pl | 119 | ||||
| -rwxr-xr-x | challenge-162/jaldhar-h-vyas/raku/ch-2.raku | 70 |
3 files changed, 190 insertions, 1 deletions
diff --git a/challenge-162/jaldhar-h-vyas/blog.txt b/challenge-162/jaldhar-h-vyas/blog.txt index e3b32e3527..fdac4eb008 100644 --- a/challenge-162/jaldhar-h-vyas/blog.txt +++ b/challenge-162/jaldhar-h-vyas/blog.txt @@ -1 +1 @@ -https://www.braincells.com/perl/2022/05/perl_weekly_challenge_week_162.html
\ No newline at end of file +https://www.braincells.com/perl/2024/02/perl_weekly_challenge_week_162.html
\ No newline at end of file diff --git a/challenge-162/jaldhar-h-vyas/perl/ch-2.pl b/challenge-162/jaldhar-h-vyas/perl/ch-2.pl new file mode 100755 index 0000000000..3ac8df86f6 --- /dev/null +++ b/challenge-162/jaldhar-h-vyas/perl/ch-2.pl @@ -0,0 +1,119 @@ +#!/usr/bin/perl +use 5.030; +use warnings; +use English; +use Getopt::Std; + +sub decrypt { + my ($table, $rtable, $m) = @_; + + my @message = grep { /[a-ik-z]/ } (split //, lc $m); + + if (scalar @message % 2) { + push @message, 'x'; + } + + my $decrypted; + + for (my $i = 0; $i < scalar @message; $i += 2) { + $decrypted .= transformDigraph($table, $rtable, $message[$i], $message[$i + 1], -1); + } + + return $decrypted; +} + +sub encrypt { + my ($table, $rtable, $m) = @_; + + $m =~ s/(.)\1/$1x$1/g; + + my @message = grep { /[a-ik-z]/ } (split //, lc $m); + if (scalar @message % 2) { + push @message, 'x'; + } + + my $encrypted; + + for (my $i = 0; $i < scalar @message; $i += 2) { + $encrypted .= transformDigraph($table, $rtable, $message[$i], $message[$i + 1], 1); + } + + return $encrypted; +} + +sub makeTable { + my ($key) = @_; + my @table = (); + + for my $letter ( grep { /[a-z]/ } (split //, lc $key)) { + if ($letter eq 'j') { + $letter = 'i'; + } + + if (! grep { $_ eq $letter} @table) { + push @table, $letter; + } + } + + for my $letter ('a' .. 'i', 'k' .. 'z') { + + if (! grep { $_ eq $letter} @table) { + push @table, $letter; + } + } + + my $n = 0; + + return map { $_ => $n++ } @table; +} + +sub reverseTable { + my ($table) = @_; + return map { $table->{$_} => $_ } keys %{$table}; +} + +sub transformDigraph { + my ($table, $rtable, $a, $b, $dir) = @_; + + my $aRow = int ($table->{$a} / 5); + my $aCol = $table->{$a} % 5; + my $bRow = int ($table->{$b} / 5); + my $bCol = $table->{$b} % 5; + if ($aRow == $bRow) { + return $rtable->{$aRow * 5 + (($aCol + $dir) % 5)} . $rtable->{$bRow * 5 + (($bCol + $dir) % 5)}; + } elsif ($aCol == $bCol) { + return $rtable->{(($aRow + $dir) % 5) * 5 + $aCol} . $rtable->{(($bRow + $dir) % 5) * 5 + $bCol}; + } else { + return $rtable->{$aRow * 5 + $bCol} . $rtable->{$bRow * 5 + $aCol}; + } +} + +sub usage { + print<<"-USAGE-"; + $PROGRAM_NAME -d -k <Str> -m <Str> + $PROGRAM_NAME -e -k <Str> -m <Str> + + -d decrypt a message + -e encrypt a message + -k <Str> key for encryption/decryption + -m <Str> message to encrypt/decrypt +-USAGE- + exit 0; +} + +my %opts; +getopts('dek:m:', \%opts); + +my $message = $opts{m} // usage(); +my $key = $opts{k} // usage(); + +my %table = makeTable($key); +my %rtable = reverseTable(\%table); + +if (defined $opts{'d'}) { + say decrypt(\%table, \%rtable, $message); +} elsif (defined $opts{'e'}) { + say encrypt(\%table, \%rtable, $message); +} else { + usage(); +}
\ No newline at end of file diff --git a/challenge-162/jaldhar-h-vyas/raku/ch-2.raku b/challenge-162/jaldhar-h-vyas/raku/ch-2.raku new file mode 100755 index 0000000000..7e3df41dbf --- /dev/null +++ b/challenge-162/jaldhar-h-vyas/raku/ch-2.raku @@ -0,0 +1,70 @@ +#!/usr/bin/raku + +sub decrypt(%table, %rtable, $m) { + my @message = $m.lc.comb.grep({ /<[a .. z]>/ }); + if @message.elems % 2 { + @message.push('x'); + } + + return @message + .batch(2) + .map({ transformDigraph(%table, %rtable, @$_[0], @$_[1], -1) }) + .join; +} + +sub encrypt(%table, %rtable, $m) { + my @message = $m.lc.subst(/ (.)$0 /, { "$0x$0" }, :g).comb.grep({ /<[a .. z]>/ }); + if @message.elems % 2 { + @message.push('x'); + } + + return @message + .batch(2) + .map({ transformDigraph(%table, %rtable, @$_[0], @$_[1], 1) }) + .join; +} + +sub makeTable(Str $k) { + my @table = $k + .lc + .subst('j', 'i', :g) + .comb + .grep({ /<[a..z]>/ }) + .unique; + + @table.push(| (('a' .. 'i', 'k' ..'z') ∖ @table).keys.sort); + + return @table.values Z=> @table.keys; +} + +sub transformDigraph(%table, %rtable, $a, $b, $dir) { + my $aRow = %table{$a} div 5; + my $aCol = %table{$a} % 5; + my $bRow = %table{$b} div 5; + my $bCol = %table{$b} % 5; + if $aRow == $bRow { + return %rtable{$aRow * 5 + (($aCol + $dir) % 5)} ~ %rtable{$bRow * 5 + (($bCol + $dir) % 5)}; + } elsif $aCol == $bCol { + return %rtable{(($aRow + $dir) % 5) * 5 + $aCol} ~ %rtable{(($bRow + $dir) % 5) * 5 + $bCol}; + } else { + return %rtable{$aRow * 5 + $bCol} ~ %rtable{$bRow * 5 + $aCol}; + } +} + +multi sub MAIN ( + Bool :$d!, #= decrypt a message + Str :$k!, + Str :$m! +) { + my %table = makeTable($k); + say decrypt(%table, %table.antipairs.Hash, $m); +} + +multi sub MAIN ( + Bool :$e!, #= encrypt a message + Str :$k!, #= key for encryption/decryption + Str :$m! #= message to encrypt/decrypt +) { + my %table = makeTable($k); + say encrypt(%table, %table.antipairs.Hash, $m); +}
\ No newline at end of file |
