Perl Weekly Challenge 032

My approach this week was to first implement solutions in Perl as a proof of concept and to determine the best approach to each of the two parts of the challenge. I then re-implemented the approach in C++, which is naturally much more verbose and requires more coding. I finished things out by exploring a Raku version.

This use of Perl as a proof of concept tool for algorithm development is one of it's classic selling points. 

Part 1

Perl

Sample Run

$ perl perl5/ch-1.pl < data
apple 3
cherry 2
banana 1

Raku

Sample Run

$ perl6 raku/ch-1.p6 < data
apple 3
cherry 2
banana 1

C++

Sample Run

$ g++ -o cxx/ch-1 cxx/ch-1.cxx
$ cxx/ch-1 < data
apple 3
cherry 2
banana 1

What I Did

The approach is to read the data (stored in a file data) from stdin. Each unique word is used as a key to a hash and each time it is seen in the file the hash value, a count, is incremented. To print the results as required dictates sorting the hash by value. This sort is readily done in Perl and Raku. C++ data structures are not so flexible. To sort a hash (i.e. a map) in C++ is best done by copying the key/value pairs to a vector and then sorting the vector by the value in the pairs. Modern C++ is able to handle all this in a somewhat surprisingly succinct way, much of the verbosity is required in order to ensure types are managed properly.

Part 2

Perl

Sample Run

$ perl perl5/ch-2.pl '{"apple":3,"cherry":2,"banana":1}'
apple      | ###############
cherry    | ##########
banana  | #####

Raku

Sample Run

$ perl6 raku/ch-2.p6 '{"apple":3,"cherry":2,"banana":1}'
apple      | ###############
cherry    | ##########
banana  | #####

C++

Sample Run

$ g++ -I /opt/local/include -o cxx/ch-2 cxx/ch-2.cxx
$ cxx/ch-2 '{"apple":3,"cherry":2,"banana":1}'

apple      | ###############  
cherry    | ##########  
banana  | #####

Notes

  • Boost provides a very nice library for handling JSON. 
  • I was previously unaware of the std::string constructor which allows for repeating a character n times (line 40). Very convenient!

What I Did

In order to maintain a common input across all three solutions I give the input in JSON format. The input JSON is given on the command line and decoded into a hash map. The same sort by value as Part 1 is performed. The sorted hash map is then iterated over and for each value

  • The value is scaled to be between 0 and 1.
  • The scaled value is multiple by the maximum bar length to determine the number of '#' characters to print.
  • The hash key and the bar representation of the value is printed.

Again Perl and Raku demonstrate the appropriateness of this approach in relatively few lines of code. C++ has more overhead required in setting up data structures and managing types but is ultimately faster, and all that managing of types provides an additional measure of safety!

Comments for this post were locked by the author