Posts

PWC 184

PWC 184 Both the tasks for this week have narrowly defined input requirements. I don't write a function to handle them. I want to avoid input validation and error handling chores, and any self-respecting function needs both. I present throwaway scripts or one-liners with the inputs explicitly written into the script or ARGV.  Challenge 1 (Sequence number) We are given a list of strings, each one formatted as two lower-case alphabets (/[a-z]/) followed by 4  numeric characters (/[0-9/), e.g.,  ('ab1234', 'cd5678', 'ef1342'). We are asked to replace the starting alphabets with a two-digit string of numbers indicating their position in the list starting with zero, e.g., ('001234', '015678', '021342'). I do this with one-liners in Perl 5, Raku and Julia. Perl 5: perl -e ' my $ctr=0; for my $x ("00" .. "99") {print $x . substr($ARGV[$ctr++],2,4) . " "; last if $ctr >= @ARGV;} print "\n"; '...

PWC 183

PWC 183 Challenge 1 (Unique array) Given an array of arrays, we are asked to remove any duplicate elements (arrays) and return the sub-array with only unique elements. Thus, given ([1,2],[3,4],[5,6],[1,2]), the script should return ([1,2],[3,4],[5,6]). Perl 5 In Perl 5, PDL offers an immediate solution via the uniqvec method. One just reads the list into a piddle: $list = pdl ([1,2],[3,4],[5,6],[1,2]); and then calls uniqvec on it: $list->uniqvec  The uniqvec method still works if the piddle has rows of unequal lengths, as in ([1,2],[3,4],[5,6,7],[1,2]). In this case, it pads the shorter rows with zeroes in the output: [     [1,2,0]     [3,4,0]     [5,6,7] ] I have presented my Perl 5 solution as a perldl executable command history. Here is my perldl script. Julia Julia has something similar to uniqvec in the unique function. println(unique(arry)) Just like PDL, it handles rows of unequal lengths. It does not pad the shorter row...

PWC 182

PWC 182 Challenge 1 (max index) Given a list of numbers, we are asked to give the index of the first occurrence of the biggest number in the list. This is easy to do via one-liners in all three languages. Here is my Raku one-liner raku -e ' say (0 .. @*ARGS.elems-1).grep({@*ARGS[$_] == @*ARGS.max}) ' 5 2 9 1 7 6 Here is my Perl 5 one-liner perl -MList::Util= ' max ' -E ' for (0 .. $#ARGV) {if ($ARGV[$_]==max(@ARGV)) {say;}} ' 5 2 9 1 7 6         It would be more compact with a trailing if as in say if (.. . ) , but I think that's just a cosmetic improvement.  I'll let the uglier syntax above stand. Julia has the convenient argmax function which returns the index of the maximum item. Here is my Julia one-liner julia -e 'println(argmax(ARGS)-1)' 5 2 9 1 7 6 My solutions differ slightly from the specification in that they return the indices of every occurrence of the biggest item, not just the first...

PWC 181

PWC 181 Challenge 1 (Sentence Order) This challenge asks us to take a given paragraph, and then: first, break it into sentences, and then sort the words and punctuation marks in each sentence into alphanumeric order print the sentences with the sorted word order Since this task does not need anything from CPAN, I did it using only Perl 4 syntax. I've done this in some earlier challenges. To add a bit of further challenge, I stuck a  use strict on top. Also, I used one single hydra-headed variable to do everything. To be precise, I used just one symbol-table entry,  main::teststring , or in Perl 4 syntax, main'teststring . Dynamic scope allows some strange things. For example, I locally redefine my &main'teststring subroutine inside the subroutine and then call the redefined subroutine from inside the original (a non-recursive call). A nested subroutine is not really needed here, but hey why not? I can't be sure that my script would actually work on a Perl 4 inter...

PWC 180

PWC 180 This week saw two light challenges, which I was able to do in both Perl 5 and Raku despite being busy at work. I also did Challenge 2 in Julia, but not Challenge 1. Challenge 1 is a string-handling task for which Julia is not a typical choice. Challenge 1 (First unique character) The challenge here is to find the first unique character in a given string.  The string is likely to be short (a long string would be unlikely to have unique characters, if naturally generated from a much smaller number of characters). So a two-loop solution should be efficient enough:  one loop to count the occurrences of each character using a hash, and  the second to loop through the characters again, checking the number of occurrences from the hash, and stopping at the first character for which the number of occurrences equals 1.  A twist is that we are asked to return the index position of the character, not the character itself.  I give my Perl 5 subroutine a somewhat retr...

PWC 179

PWC 179 These are somewhat quick and dirty attempts as I have less spare time this week. Challenge 1 (ordinal numbers) Challenge 1 asks for a numeric input to be represented in words (in English) as an ordinal number, e.g., 62 -> sixty-second. The easiest way to do this in Perl 5 is via the Lingua::EN::Numbers package or one of its relatives. The ready-made num2en_ordinal subroutine does what we need. In Raku, it is easiest to use Lingua::EN::Numbers again via Inline::Perl 5. In Julia too, I just run Perl 5 one-liners using Julia's backtick notation ( documented here ). So effectively I have three Perl 5 scripts wrapped slightly differently. Here is my Perl 5 script. Here is my Raku script. Here is my Julia script.   I found out later that Raku has its own Lingua::EN::Numbers , so one doesn't have to call the Perl 5 module. Challenge 2 (Unicode sparkline) Sparklines are inline graphics. We are asked to represent an array of numbers as a sparkline using unicode characters....

PWC 178

PWC 178 I didn't have time to do the full challenge in both Perls + Julia this week, so I have just submitted Challenge 1 in Raku, and Challenge 2 in Perl 5. The choice of language for each challenge is because of the availability of modules that make the respective task easy. I also did a partial solution to Challenge 1 in Julia. Challenge 1 (Quater-imaginary base) This is an offbeat number base proposed by Donald Knuth: base 2i. Read all about it in Wkipedia. We are asked to convert a given base-10 number to base-2i. It is trivial to do this in Raku because of the Base::Any module which converts a number from (almost) any number base to (almost) any number base. (The almost is because it does not handle complex bases with both a real and imaginary part. The wholly imaginary 2i is no problem). This allows easy conversion of any real or complex base-10 number, as I illustrate with a couple of examples from the wikipedia page (accessed 2022-8-17). Here is my Raku solution. Julia h...

PWC 177

PWC 177 Challenge 1 (Damm Algorithm) This challenge requires implementing the Damm algorithm which uses an extra check digit to catch errors in entering digits in a numeric code, especially the common transposition errors. In terms of programming, this is a simple matter of setting up a lookup table and then looking it up. I implement two subroutines, closely following the howto in the wikipedia page. "get_check_digit" calculates a check digit for a given number, and "validate" checks if a number is correct based on the extended number including a check digit. In Perl 5 and Raku, I give in to dark primitivist urges and set up the lookup table as a flat list of strings. In Julia, it is easy to implement it as a Matlab-like matrix. This algorithm is useful enough to have its own CPAN module: Algorithm::Damm Here is my Perl 5 script. Here is my Raku script. Here is my Julia script. Challenge 2 (Palindromic Prime Cyclops) This challenge requires looking for the first 2...

PWC 176

PWC 176 Challenge 1 (Permuted multiples) We are asked to find the smallest number x such that x , 2 x, 3 x , 4 x , 5 x and 6 x all have the same digits in common (not in the same order obviously) and no other digits. The answer is 142857.    I started with Raku. Looping through the integers, for each multiple, 2x, 3x etc., I used comb to get a list of digits and then sort to get them sorted and then gist to stringify them, and then compared this to the combed, sorted and stringified original number x. This translates easily to both Perl 5 and Julia. In Perl 5 I used a sub to do the equivalent of combing and sorting and then joined the array back into an Int. Here is my Raku script Here is my Perl 5 script Here is my Julia script   Here it is as a Raku one-liner:   raku -e '(1 .. 200_000).grep({$_.comb.sort.gist eq (6*$_).comb.sort.gist}).grep({$_.comb.sort.gist eq (5*$_).comb.sort.gist}).grep({$_.comb.sort.gist eq (4*$_).comb.sort.gist}).grep({$_.comb.sort.gist e...

PWC 175

PWC 175 Challenge 1 -- Last Sunday Challenge 1 asks us to find the last Sunday of every month in a particular year, say 2022. This is easy to do in Perl thanks to the Date::Manip suite of modules, which bristles with options, including a straightforward way to do this. The specific module useful here is Date::Manip::Recur With this module it's as easy as saying: $date_recur_object -> parse( " last Sunday of every month in 2022 " ); which is exactly what I do. In Raku, it's a bit more difficult, but still easy via Raku's excellent and well-documented built-in Date objects. Pretty much a matter of looping through the last 10 days of each month, picking up the Sundays in that stretch, and then keeping the last Sunday. Julia is similar to Raku in its Dates handling, except that the Dates are not built-in, but a short library call away. I could have translated my Raku script line-for-line to Julia, but I have the minor difference that I used multiple dispatch in R...

PWC #174

PWC #174 Challenge 1 (Disarium Numbers) For challenge 1, we are tasked to find the first 19 disarium numbers . These are base-ten positive integers "abc..." such that a^1+b^2+c^3 ... = abc... (I don't know how to type Math in this blog platform, so I use something like Excel formula syntax, with which readers should be familiar) For example, 518 is a disarium number, because 5+1^2+8^3 = 518.  There are only 20 disarium numbers, with the 20th being a 20-digit monster. The first 10 are mechanically the single-digit numbers from 0 through 9. The 19th is a 7-digit number around 2.6 million. I used a brute-force approach of just going through all the numbers from 0 to 3_000_000, and selecting the ones which meet the disarium condition. But a more efficient strategy exists, which I sketch below, but did not implement in most of my scripts. The brute force approach is fast enough for the first 19 items. More efficient algorithm (but I use brute force for my main submission) Cons...

PWC #173

PWC #173 Challenge 1 (Esthetic numbers) Esthetic numbers are numbers in which consecutive digits are either one less or one more than the (previous or next) other digit. For example, 5_654 is an esthetic number but 120 is not. We are asked to find a function that tells us whether a particular input number is esthetic or no. This seems like a good candidate for a regex solution, but I wound up just looping through the characters in the number (as a string) and checking if the next character was one more or less. If not, then it is not esthetic, otherwise it is. I also check that the input is numeric (otherwise not esthetic). In Perl and Raku, I check for and drop the "_" character used as a thousands separator. I have not considered single-digit numbers, the algorithm assumes the number is at least two digits (easy to fix, but I'll leave it). The internet tells me that single-digit numbers are esthetic by convention. My if condition is unnecessarily clunky, I check separa...