Perl Weekly Challenge, First Week

I am glad that Mohammad Anwar started the Perl Weekly Challenge. Since it seems that the entries will not be published by Mohammad, this gives me the opportunity to finally publish my first post here, about 8 months after having registered.

Week 1, Challenge # 1: Letter Substitutions

Substitute every ‘e’ with upper-case 'E' in the string “Perl Weekly Challenge” and count every occurrence of ‘e’.

For this challenge, I proposed only a Perl 5 solution, in the form of a Perl one-liner:

$ perl -E 'my $c = shift; my $num = $c =~ tr/e/E/; say $c; say "Number of replacements: $num";'  'Perl 6 Weekly Challenge'
PErl 6 WEEkly ChallEngE
Number of replacements: 5

Nothing special about it, except that the tr/// operator returns the number of substitutions it has performed, so there is no need to count separately the 'e'.

I did not submit any Perl 6 entry for that (I wasn't sure I could submit two entries), but we could use almost the same code, this time under the Perl 6 REPL:

> my $string = 'Perl Weekly Challenge';
Perl Weekly Challenge
> my $distance = $string ~~ tr/e/E/;
StrDistance.new(before => "Perl Weekly Challenge", after => "PErl WEEkly ChallEngE")
> say $string;
PErl WEEkly ChallEngE
> say +$distance;
5

In Perl 6, the tr/// operator does not return a substitution count, but a StrDistance object that measures the distance between original value and the resultant string., All we need to change (compared to P5) is to use the prefix + operator to numify the string distance object into a substitution count.

Week 1, Challenge # 2: Fizz Buzz

Program a one-liner that solves the Fizz Buzz challenge for every integer from 1 through 20. But if the integer is divisible with 3 or 5 or both, the integer should be replaced with fizz, buzz or fizz buzz respectively.

Perl 5 One Liner:

$ perl -E 'say $_ % 15 ? $_ % 3 ? $_ % 5 ? $_ : "buzz" : "fizz" : "fizz buzz" for (1..20); '
1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizz buzz
16
17
fizz
19
buzz

Note that, since I wanted to avoid comparing the result of the modulo operator to 0, the ternary operators are nested, which is not the most usual way to use several ternary operators. This is the code of the oneliner reformatted for better comprehension:

say $_ % 15 ? 
    $_ % 3  ? 
    $_ % 5  ? 
              $_ : 
              "buzz" : 
              "fizz" : 
              "fizz buzz" 
    for (1..20);

And the same in Perl 6 (we could use the given ... when construct, but I decided it was more fun to do it similar to the P5 version using the ternary operator. Note that this one-liner is on Windows (so the single and double quotes are swapped), because I din't have access to my Linux box where P6 is installed.)

C:\Users\Laurent>perl6 -e "for 1..20 -> $c { say $c %% 15 ?? 'fizz buzz' !! $c %% 3 ?? 'fizz' !! $c %% 5 ?? 'buzz' !! $c;}"
1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizz buzz
16
17
fizz
19
buzz

Since I'm using here the Perl 6 %% divisibility operator, the logic flow is simpler than for the P5 version (the ternary operators are chained, rather than nested).

Just a small additional note: Mohammad really asked for title-case "Fizz, Buzz and Fizz Buzz," but I did not consider those upper-case letters to be part of the specification.

The second week challenge is already started, and I have already submitted my entries by mail, but since I don't want to spoil anyone, I'll post my entries only after the submission expiration date (Sunday, April 7, 2019). If you're interested in participating in this challenge, make sure you answer before 6 p.m. BST (British summer time) on that date.

1 Comment

Thanks Laurent for spreading the word.

Leave a comment

About laurent_r

user-pic I am the author of the "Think Perl 6" book (O'Reilly, 2017) and I blog about Perl (5 and 6).