Continues from previous post. Follow up on this week review of Perl Weekly Challenge #009 answers submitted by all the participants. Read the full question list and the recap of the challenge to have an overview before we proceed with our review.
Challenge #1
Since most first question is beginner friendly, there are two steps to solve the problem. First, we need to loop through a series of numbers. Next, determine whether a square number has at least five distinct digits. While this is quite a straight forward question, nevertheless, all participants have different approach to tackle this. For the first step on looping and when to end the loop, there is a do and until
way (Adam Russell and Andrezgz), while
way (Steven Wilson), while and exit
way (Dave Jacoby and Joelle Maslak), while and last
way (Jaldhar H. Vyas and Yozen Hernandez), postfix while
control structure way (Daniel Mantovani and Guillermo Ramos), for
way (Gustavo Chaves and Maxim Nechaev), and lastly for and last
way (Athanasius, Ruben Westerberg, and Laurent Rosenfeld).
Only two participants used iterator (Dave Jacoby and Laurent Rosenfeld) to generate the series of number. Laurent pushed it further with closures and anonymous code reference. Will we see more answers using such technique in coming challenges?
To determine a number has at least five distinct digits, it can done with several ways. Using hash to record which digits have been seen is the common approach used by most participants through map
or postfix for loop
(Athanasius, Ruben Westerberg, Guillermo Ramos), regex (Yozen Hernandez), and using List::Util
module (Joelle Maslak and Dave Jacoby). Off course, since we’re using Perl and it’s a simple problem, there is the oneliner solution by Laurent Rosenfeld.
The unorthodox solution came from Yozen Hernandez. Note the calculation of square number and the use of regular expression.
# Start with the root of the first $ndigit square
# or closest integer
my $root= int( sqrt( 10**( $n  1 ) ) );
while ( 1 ) {
# Use positive lookahead to get rid of duplicate digits
( my $dedup = $root**2 ) =~ s/(.)(?=.*?\1)//g;
last if ( length($dedup) >= $n );
$root++;
}
say $root**2;
Challenge #2
Compare to challenge #1, this question was more complicate and most solutions were quite lengthy and it took a while to digest. Kudos to Dave Jacoby for written lengthy comment on his solution and explanation on different Perl’s quirky syntax usage. For a start, do look into the solution by Gustavo Chaves which gave a quick overview on how ranking works. Generally, we can break down the solution into three step of getting the data either as array or hash, sorting the data in descending order, and lastly ranking the data according to different ranking strategies. Athanasius’ solution was a good example of a wellorganized code that follows such structure. Furthermore, he also added additional ordinal and fractional ranking algorithms as well. The implementation of Dispatch Table that map to different subroutine ranking algorithms was nice addition to make the code even more readable and organized.
const my %RANKINGS => (
Standard => \&rank_data_standard,
Modified => \&rank_data_modified,
Dense => \&rank_data_dense,
Ordinal => \&rank_data_ordinal,
Fractional => \&rank_data_fractional,
);
There were two approaches on how to structure the ranking codes, either use one subroutine to pick the ranking strategies (Daniel Mantovani and Guillermo Ramos), use three separate subroutines (Adam Russell, Dave Jacoby, Athanasius, Ruben Westerberg, Laurent Rosenfeld, Jaldhar H. Vyas, and Steven Wilson), or just a single loop to show case three different algorithms (Andrezgz and Joelle Maslak).
On a related note, the Tie::Hash::Rank
and List::Rank
are the only CPAN modules that maybe useful to solve this challenges. However, nobody is exploring this approach.
Challenge #3
Only Maxim Nechaev and Joelle Maslak have submitted their solutions to this challenge. Low submission most likely due to this is an optional question and Joelle’s solution was probably the standard modern approach to solve this problem. Nevertheless, we should wait and see what alternative ways to solve this third challenge. Joelle’s solution is similar to last week challenge with minor changes to API URL endpoints and parameters. On the other hand, Maxim provided an alternative solution to connect to the API using SMTP protocol instead of HTTP.
Related blog posts related to this week challenge.

Arne Sommer. The regular solutions as well code walk through through using Perl 6.

Adam Russell. Very detailed writeup on his approaches to both solutions.

Dave Jacoby. Read his note on solving Challenge #1 and #2.

Francis Whittle. A different take on Perl 6 solutions for both challenges.

Joelle Maslak. Read this if you want to know how to solve Challenge #3.

Laurent Rosenfeld. If you need to read and compare both Perl 5 and 6 solutions. His approach on using iterator, closures, and anonymous code references for Challenge #1 is a must read.

Yozen Hernandez. If you want to know more on why he use regex for Challenge #1 and how he use country data for Challenge #2.