Kian-Meng Ang Weekly Review: Challenge - 012

Thursday, Jun 20, 2019| Tags: Perl

Continues from last week.

For a quick overview, read through all questions and recap of the challenge first.

This week was quite unique as we observed there were several submissions where submissions were based on existing solutions but were done in a more alternative and elegant way. Moreover, some of these show case the expressiveness of Perl programming language itself, which is also one of the key goal of this weekly challenge.

Challenge #1

One of the key takeaway from this challenge was the solution by Joe Tym. Based on the solution done by Laurent Rosenfeld, he refactored it to use different CPAN modules like PDL (which is the equivalent to Python’s NumPy) and Math::Prime::FastSieve and did a benchmark comparing different modules combination and NumPy solution on calculating prime number. His result as shown below. And he should definitely should create a blog and write about it about it.

PDL Only                    -> 0m0.340s
Math::Prime::FastSieve+PDL  -> 0m0.337s
Math::Prime::FastSieve Only -> 0m0.188s

Benchmark results, just to generate prime numbers 0-10 million:

Pure Perl implementation(above) -> 0m26.662s
PDL implementation(below)       -> 0m0.284s
NUMPY(1.8.2) implementation:    -> 0m0.129s
Math::Prime::FastSieve          -> 0m0.122s

Perl script that does nothing, just use PDL;        -> 0m0.132s
Python script that does nothing, just import numpy; -> 0m0.066s

And as usual, some alternative (non-Perl implementation) or creative ways used by participants to find, generate, determine prime numbers. Instead of generating prime numbers within the script itself, Adam Russell downloaded a list of pre-generated prime numbers. While Duncan C. White had a similar approach, but wrote a C program to generate prime numbers instead. Compare to other participants which use formulae to determine primality, Daniel Mantovani used regex to determine a prime number. For Yozen Hernandez, look into his solution or even better, read his blog post on how he used closure and iterator to solve the problem.

The second key takeaway of this challenge was the solution implemented by Joelle Maslak. Remember that Duncan C. White wrote a C program to generate prime numbers? Well, Joelle Maslak took similar approach to determine prime number. This was done through the Inline module where you can code a Perl subroutine in other programming language. In this case, the C code was embedded in the Prime package and there was a fallback Perl subroutine in case the script cannot load the package. By far, the cleanest polyglot programming solution.

Challenge #2

Mark Senn illustrated the solution of the problem clearly by breaking down echo path into its individual components in a table form as shown below. Generally, this was the common approach took by all participants.

# Split @path into its separate parts and put
# the results in the two dimensional @part array.
#   0 1  2  3  4  5
# 0   a  b  c  d
# 1   a  b  cd
# 2   a  b  cc
# 3   a  b  c  d  e

On splitting a string into each array elements to build the above two dimensional array, two things we learned here. Daniel Mantovani discovered that setting the third argument of split function to a negative limit will treat /a/b and /a/b/ differently. Adam Russell was the only participant that used quotemeta when splitting the string.

The only difference was how each participant find the common elements or intersection of all paths in array form. To find the prefix or common paths, some have used the splice  function (Alicia Bielsa, Gustavo Chaves, Steven Wilson, Andrezgz), most compare each array element (Athanasius, E. Choroba, Dave Jacoby, Adam Russell, Joelle Maslak, Yozen Hernandez, Duncan C. White, Laurent Rosenfeld, Ruben Westerberg, Shardiwal), regex (Jaime), reduce function (Feng Chang), grep function (Jaldhar H. Vyas), all function (Maxim Nechaev), and intersection function (Kian-Meng Ang).

Challenge #3

We have four people (Athanasius, Steven Wilson, Joelle Maslak (Perl 5 and Perl 6), and Kian-Meng Ang) participated for this week. It would be nice if we can maintain or have more submissions to this challenge. While some solutions may seem similar from week to week, we still hope to see more different and creative approaches to tackle this challenge.

The HTTP client CPAN modules used for this week are LWP::UserAgent, HTTP::Tiny, LWP::Simple, Mojo::UserAgent, and Cro::HTTP::Client (Perl 6). Note that LWP::Simple is just a simple wrapper of LWP::UserAgent module and it’s suitable for simple one-liner or small script. Steven Wilson’s solution is a good example that demonstrated such style. While HTTP::Tiny, a minimal CPAN module with non-core dependencies, can do the job as well, it’s more suitable for simple HTTP request like grabbing a page, downloading or mirroring a file. You still need external dependencies to process the JSON or XML responses. Alternatively, Mojo::UserAgent may seem complex, is a complete CPAN module for handling web service API due to its built-in support for JSON and XML processing as well as other extra features. Joelle Maslak’s solution in Perl 6 let us have a glimpse of Cro::HTTP::Client usage and a more consistent way of doing web development in Perl 6.

Three things that caught our attention this week.

First, Athanasius showed us that parsing XML string is still a tricky thing even though with the help of XML::LibXML module. Using XML::Hash::XS module to convert an XML document to hash may help to remove the parsing code.

Second, Steven Wilson use of Perl6::Form module to prettify the output and turned it into something like a flash card as shown below. A nice touch over the dull console output, right? Is there any other CPAN modules that can make the console output more interesting?

$ perl help
| HELP                                      |
| the activity of contributing to the       |
| fulfillment of a need or furtherance of   |
| an effort or purpose                      |
| SYNONYMS                                  |
| help, service, supporter, assistance,     |
| attention, financial aid, care, assist,   |
| helper, economic aid, avail, assistant,   |
| tending, aid                              |

Third, if you have problem access the API key and want to simulate local testing scenario, you can do what Joelle Maslak did with a mock API server locally through Mojolicious::Lite.

Blog Posts

Some additional write-ups from the participant from this challenges.

(1) The Euclid Path with Perl 6 by Arne Sommer. Step-by-step walk through with Perl 6.

(2) Perl Weekly Challenge - 012 by Mark Senn. He’s back and another details write-up using Perl 6.

(3) Perl Weekly Challenge 012 by Adam Russell. Is he going for another over-engineered solutions?

(4) Euclid and Reduce by Dave Jacoby. Good write-up on how he solved the challenge #1.

(5) Perl Weekly Challenge # 12: Euclid’s Numbers and Directories by Laurent Rosenfeld. If you need to compare solutions between Perl 5 and 6.

(6) Perl Weekly Challenge 12: Euclid Numbers and Common Paths by Yozen Hernandez. Read up if you want to know more on using closure and iterator.

(7) Perl Weekly Challenge 012: Non-Prime Euclid Numbers and the Common Path by E. Choroba. Complementary write-up to Laurent Rosenfeld.

(8) Perl Weekly Challenge 12 – Euclid Numbers by Joelle Maslak. A very detailed explanation on challenge #1.


If you have any suggestions or ideas then please do share with us.

Contact with me