Perl Weekly Challenge
The Perl Weekly Challenge is an amazing project run by Mohammad Anwar that provides coding challenges on a weekly basis; and more importantly a good variety of approaches written up (or shared as video) by developers in Perl and other programming languages.
This week for example the challenges are/were:
TASK #1: Reverse Words
You are given a string $S. Write a script to reverse the order of words in the given string. The string may contain leading/trailing spaces. The string may have more than one space between words in the string. Print the result without leading/trailing spaces and there should be only one space between words.
TASK #2: Edit Distance
You are given two strings $S1 and $S2. Write a script to find out the minimum operations required to convert $S1 into $S2. The operations can be 'insert', 'remove' or 'replace' a character.
Solving the challenge can be a challenge of finding an approach that works, though sometimes they are also simple. When simple I have found it enjoyable and rewarding to use it as a code kata where I might try different approaches or try solving in multiple programming languages.
So this weeks is one of those ones that clicked in my head so here is a small overview of my solution:
Here is the test...
# t/pw96.t
use strict;
use warnings;
use Test2::V0 -target => 'pw96';
my $input = 'The Weekly Challenge';
my $expected = 'Challenge Weekly The';
is $CLASS->reverse_words($input),
$expected,
'Example one is correct';
$input = ' Perl and Raku are part of the same family ';
$expected = 'family same the of part are Raku and Perl';
is $CLASS->reverse_words($input),
$expected,
'Example two is correct';
done_testing;
So as I have mentioned in other places, I default to Test2:V0 where possible. It's modern and full featured. It is a solid "Batteries included" testing library. This is a pretty basic set of tests.
Here is the code that followed the tests...
# lib/pw96.pm
package pw96;
use strict;
use warnings;
use Moo;
sub reverse_words {
my ($self, $phrase) = @_;
my @words = split ' ', $phrase;
return join ' ', reverse @words;
}
1;
As you can see it's pretty simple; though in fact it's more complex than actually required.
Why?
Because I have another "default setting", I tend to use the Moo module for some object orientation ease. I don't "need" it so technically I am not doing the "simplest thing that works" depending on how you define simple. In the situation of doing this sort task; using a comfortable setup (Test2::V0 and Moo) means consistency which makes it simple over time?
This is more the making things simple to write, rather than writing the simplest thing.
At this stage I should point out that I did TDD this code; so the first thing I wrote was this:
use Test2:V0 -target => 'pw96';
done_testing;
The above failed, as I had not created the lib/pw96.pm file. So I created that with a little boiler plate:
package pw96;
1;
Which made the test pass. Next I tested for the method I wanted to write add in:
can_ok($CLASS, 'reverse_words');
After watching that fail, I added this in the module:
use Moo;
sub reverse_words{}
All good! After which I added my first practical test (and deleting the can_ok test).
my $input = 'The Weekly Challenge';
my $expected = 'Challenge Weekly The';
is $CLASS->reverse_words($input),
$expected,
'Example one is correct';
After which I wrote the method in a basic way. Once that was working; I refined it to the two line solution. You could take it down a bit more; but where it sits is a nice balance of conciseness and simplicity to read.
So there you have it my solution to this weeks Perl Weekly Challenge.