๐Ÿ“˜ Caesar cipher using Perl 6

Encode a message using the Caesar cipher technique.

The Caesar code is a simple method of transcoding the letters of the message so that each letter is replaced with the letter that occurs in the alphabet N positions earlier or later.

For example, if N is 4, then the letter e becomes af is transformed to b, etc. The alphabet is looped so that z becomes v, and letters a to d become w to z.

The Str data type in Perl 6 is equipped with the trans method, which we have seen in Task 10, DNA-to-RNA transcription. It is also quite easy to use ranges in the replacement recipe:

my $message = 'hello, world!';

my $secret = $message.trans(
                 ['a' .. 'z'] => 
                 ['w' .. 'z', 'a' .. 'v']
             );
say $secret; dahhk, sknhz!

You can read the original message by translating it back with the same method but with swapped arrays:

say $secret.trans(
    ['w' .. 'z', 'a' .. 'v'] => 
    ['a' .. 'z']
);

Try modifying the solution so that it also works with the strings containing capital letters.

๐Ÿ“˜ DNA-to-RNA transcription using Perl 6

Convert the given DNA sequence to a compliment RNA.

Weโ€™ll not dig deep into the biology aspect of the problem. For us, it is important that the DNA is a string containing the four letters A, C, G, and T, and the RNA is a string of A, C, G, and U. The transformation from DNA to RNA happens according to the following table:

DNAACGT
RNAUGCA

In the Str class in Perl 6, the trans method is defined; it takes pairs โ€˜old characterโ€”new characterโ€™. So, to translate from DNA to RNA, letโ€™s write the above table as a hash and use it with the transmethod:

my %transcription =
    A => 'U', C => 'G', G => 'C', T => 'A';

my $dna = 'ACCATCAGTC';
my $rna = $dna.trans(%transcription);
say $rna; # UGGUAGUCAG

The trans method accepts a few attributes that alternate its behaviour. For example, the :squash attribute removes the duplicated characters. This probably does not make sense in biology, but works for us an exercise:

say $dna.trans(%transcription, :squash); # UGUAGUCAG

It is also possible to replace the sequences of more than one character. For example:

say $dna.trans('ACCA' => 'UGGU', 'TCA' => 'AGU',
               'GTC' => 'CAG');

๐Ÿ“˜ Generating random passwords using Perl 6

Generate a random string that can be used as a password.

One of the possible solutions looks like this:

say ('0' .. 'z').pick(15).join('');

The pickmethod with no arguments takes a random element from the range of the ASCII charactersbetween 0and z. In the above example, calling pick(15) selects 15 different characters, which are then joined together using the join method.

It is important to know the two key features of the pick method. First, when called with an integer argument bigger than 1, the result contains only unique elements. Thus, all the characters in the password are different.

The second feature is a consequence of the first one. If the provided list of elements is not long enough, and its length is less than the argument of pick, the result is as long as the original data list.

To see which elements are used for generating a password, run the code with a number bigger than the whole ASCII sequence:

say ('0' .. 'z').pick(1000).sort.join('');

With this request, you will see all the characters that participate in forming a random password:

0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`
abcdefghijklmnopqrstuvwxyz
An example of a generated password: 05<EV]^bdfhnpyz.

To limit the character range, list the characters you want to see in a password:

my @chars = '0' ... '9', 'A' ... 'Z', 'a' ... 'z';
say @chars.pick(15).join('');

Now the password only contains alphanumeric symbols: 2zOIySp5PHb08Ql.

The ... operator creates a sequence. Be warned not to use the .. operator, which creates a range, in which case the @chars array is an array of ranges rather than a flat array of single characters.

The solution is quite elegant and does not require explicit use of the randfunction. Neither loops are needed.

Now, let us solve the task in such a way that characters may be repeated in the result. It is still possible to use the pickmethod but it should be called independently a few times.

my $password = '';
$password ~= ('0' .. 'z').pick() for 1..15;
say $password;

Now, the password can include the same character more than once, for example: jn@09Icoys@tD;o.

Finally, let us stick to the intermediate solution, where the password is formed via a few groups of random strings, and each such substring contains only unique characters:

my $password = '';
$password ~= ('0' .. 'z').pick(5).join('') for 1..3;
say $password;

As the pick returns a sequence, the join method is needed to concatenate characters to a string with no gaps.

๐Ÿ“˜ Incrementing filenames using Perl 6

Generate a list of filenames like file1.txt, file2.txt, etc.

Perl 6 allows incrementing those kinds of filenames directly:

my $filename = 'file0.txt';
for 1..5 {
   $filename++;
    say $filename;
}

This program prints the list of consequent filenames:

file1.txt
file2.txt
file3.txt
file4.txt
file5.txt

Notice that after reaching 9, the letter from file is incremented. Thus, file9.txt is followed by filf0.txt. To prevent that, add enough zeros in the template:

my $filename = 'file000.txt';
for 1..500 {
   $filename++;
    say $filename;
}

Now, the sequence starts with file001.txt and continues to file500.txt. Multiple file extensions in the template, say file000.tar.gz, are also handled properly, so the numeric part is incremented.

๐Ÿ“˜ Camel case using Perl 6

Create a camel-case identifier from a given phrase.

It is a good practice to follow some pattern when choosing names for variables, functions, and classes in any programming language. In Perl 6, identifiers are case-sensitive, and, unlike many other languages, hyphens are allowed. So, variables names like $max-span or function names like celsius-to-fahrenheit are accepted.

In this task, we will form the CamelCase variable names from a given phrase. Names created in this style are built of several words; each of which starts with a capital letter.

Hereโ€™s the program that does the required conversions:

my $text = prompt('Enter short text > ');
my $CamelName = $text.comb(/\w+/).map({.lc.tc}).join('');
say $CamelName;

All the actions are done in a sequence of method calls. The words are selected from the input $text using the comb method with a regex /\w+/. Then, each found word is mapped using another chained method call: 

{ .lc.tc }

A โ€˜bareโ€™ dot means that the method is called on the default variable $_, which is repeatedly set to the current element. In Perl 6, there is no ucfirst method to make the first letter of the text uppercase. Instead, we use the tc method (tc stands for Title Case), and call it on the result of the lc call to make sure that after calling .lc.tc, all the letters are lowercase except the first one. Finally, the elements of the array are joined together with the help of the join method. The input string โ€˜Hello, World!โ€™ becomes HelloWord after all the transformations are done.

๐Ÿ“˜ Removing blanks from a string using Perl 6

Remove leading, trailing and double spaces from a given string.

This task often occurs when you need to clean the user input, such as from web forms, where leading or trailing spaces in, for example, names, are most likely user mistakes and should be removed.

Removing double and multiple spaces between words can be solved by using substitution:

my $string = 'Hello,     World!';
$string ~~ s:g/\s+/ /;

Donโ€™t forget to make the substitution global with the :g adverb to find all the occurrences of repeated spaces.

Leading and trailing spaces can be removed with the trimroutine:

my $string = 'Hello, World! ';
say trim($string);

The trim routine exists as a self-standing function, as shown in the previous example, as well as a method of the Str class, so it can be called on a variable or on a string:

say $string.trim;
say ' Hello, World! '.trim;

There are also two routines, trim-leading and trim-trailing, which remove either only leading or only trailing spaces.

say 'ยก' ~ '  Hi '.trim-leading;  # ยกHiโฃโฃ
say '  Hi  '.trim-trailing ~ '!'; # โฃโฃHi!

๐Ÿ“˜ Reverse a string using Perl 6

Print a string in the reversed order from right to left.

Strings, or the objects of the Str class, have the flip method, which does the work:

my $string = 'Hello, World!';
say $string.flip;

This code prints the desired result:

!dlroW ,olleH

Theย flip routine may be called both as a method on a string and as a stand-alone function:

say flip 'Abcdef'; # fedcbA
say 'Word'.flip;   # droW

Donโ€™t forget thatย say can also be called as a method:

'Magic'.flip.say; # cigaM

In Perl 6, there is also theย reverse routine, but it cannot be applied directly to strings. It accepts lists, so a string first has to be converted to the list of characters, then reversed, and later joined again to a string.

Here is the code that works according to this description.

my $string = 'Hello, World!';
my $reversed = $string.split('').reverse().join('');
say $reversed; # !dlroW ,olleH