Perl Weekly Challenge 45: Square Secret Code and Source Dumper
These are some answers to the Week 45 of the Perl Weekly Challenge organized by Mohammad S. Anwar.
Task # 1: Square Secret Code
The square secret code mechanism first removes any space from the original message. Then it lays down the message in a row of 8 columns. The coded message is then obtained by reading down the columns going left to right.
For example, the message is “The quick brown fox jumps over the lazy dog”.
Then the message would be laid out as below:
thequick
brownfox
jumpsove
rthelazy
dog
The code message would be as below:
tbjrd hruto eomhg qwpe unsl ifoa covz kxey
Write a script that accepts a message from command line and prints the equivalent coded message.
Square Secret Code in Perl
Let’s do a first program implementing the task exactly as described:
use strict;
use warnings;
use feature "say";
my $msg = shift // "The quick brown fox jumps over the lazy dog";
$msg =~ s/\s+//g;
$msg =~ s/(.{8})/$1\n/g;
my @lines = split /\n/, $msg;
for my $i (0..7) {
print map { substr $_, $i, 1 if length $_ >= $i} @lines;
print " ";
}
This works as expected:
$ perl square.pl "The quick brown fox jumps over the lazy dog"
Tbjrd hruto eomhg qwpe unsl ifoa covz kxey
But we don’t really need to lay out the message over rows of 8 characters and can simplify a bit the code using an array of strings as follows:
use strict;
use warnings;
use feature "say";
my $msg = shift // "The quick brown fox jumps over the lazy dog";
$msg =~ s/\s+//g;
my @letters = map { /.{1,8}/g; } $msg;
for my $i (0..7) {
print map { substr $_, $i, 1 if length $_ >= $i} @letters;
print " ";
}
This produces the same output as before.
Square Secret Code in Raku
Here, we’re just porting the second Perl version above:
use v6;
my $msg = @*ARGS ?? shift @*ARGS
!! "The quick brown fox jumps over the lazy dog";
$msg ~~ s:g/\s+//;
my @letters = map { ~ $_}, $msg ~~ m:g/ .**1..8/;
for 0..7 -> $i {
print " ", join "", map { substr $_, $i, 1 if .chars >= $i}, @letters;
#print " ";
}
This displays the following output:
$ perl6 square.p6 "The quick brown fox jumps over the lazy dog"
Tbjrd hruto eomhg qwpe unsl ifoa covz kxey
Task # 2: Source Dumper
Write a script that dumps its own source code. For example, say, the script name is ch-2.pl then the following command should return nothing.
$ perl ch-2.pl | diff - ch-2.pl
Source Dumper in Perl
In Perl, the $0
special variable contains the name of the program. So, it is just a matter of opening the file and printing its lines:
use strict;
use warnings;
my $progr = "./$0";
open my $IN, "<", $progr or die "Unable to open $progr $!";
print while <$IN>;
close $IN;
Running the program duly prints its contents:
$ perl pgm_dump.pl
use strict;
use warnings;
my $progr = "./$0";
open my $IN, "<", $progr or die "Unable to open $progr $!";
print while <$IN>;
close $IN;
And a diff
between the program output and the program code prints out nothing:
$ perl pgm_dump.pl | diff - pgm_dump.pl
Source Dumper in Raku
In Raku, the program name (and path) is contained in the $?FILE
compile-time variable. So solving the task is very easy:
use v6;
my $progr = "$?FILE";
$progr.IO.slurp.say;
which duly prints:
$ perl6 pgm_dump.p6
use v6;
my $progr = "$?FILE";
$progr.IO.slurp.say;
Actually, we don’t need the intermediate $progr
variable:
use v6;
$?FILE.IO.slurp.say;
which also prints the expected output:
$ perl6 pgm_dump.p6
use v6;
$?FILE.IO.slurp.say;
Wrapping up
The next week Perl Weekly Challenge is due to start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on Sunday, February 9. And, please, also spread the word about the Perl Weekly Challenge if you can.
Leave a comment