Posts

PWC 235

PWC 235 I tried to restrict to Perl 4 syntax for both challenges this week, as documented in Rex Swain's Perl 4 reference or the 1st edition of Programming perl. I do use nested subroutines, which I am not sure would actually work in Perl 4, though they comply with the syntax. My programs are tested on Perl 5.38. (The -l in the shebang line works only in Perl 5. The Perl 4 equivalent was -L012 [in Unix], which is no longer available.) My solutions to this week's challenges highlight the usefulness of the splice array operator. Challenge 1 (Remove One) We are given an array of integers and asked to verify if removing any one element will leave the remaining elements in monotonically ascending order. A helper sub-subroutine &ascending checks if a particular array is in ascending order, by comparing it element-by-element to its sorted version. Here it is:      local *ascending = sub {         local @ascending=(sort {$a <=> $b} @_);         foreach (0 .. $#_) {($_[

PWC 234

PWC 234 I tried to restrict to Perl 4 syntax for both challenges this week, as documented in Rex Swain's Perl 4 reference or the 1st edition of Programming perl. I do use nested subroutines, which I am not sure would actually work in Perl 4, though they comply with the syntax. My programs are tested on Perl 5.38. (The -l in the shebang line works only in Perl 5. The Perl 4 equivalent was -L012 in Unix, which is no longer available.) As I have mentioned before, my aims in using the old syntax are just mild nostalgia plus to add a bit of additional challenge to the task. I know that this is not the most efficient or idiomatic way to do things today. But I should observe that it is really cool that I am able to write code using 30-year old syntax, and run it unmodified on the latest Perl 5.38. You cannot do this with Python 3 for example. This very deep backward compatibility is one of those unsung underappreciated beauties of Perl 5. In my opinion, it is a very cool thing in

PWC 233

PWC 233 I tried to restrict to Perl 4 syntax for both challenges this week, as documented in Rex Swain's Perl 4 reference or the 1st edition of Programming perl.  As I have mentioned before, my aims in using the old syntax are just mild nostalgia plus to add a bit of additional challenge to the task. But I should observe that it is really cool that I am able to write code using 30-year old syntax, and run it unmodified on the latest Perl 5.38. You cannot do this with Python 3 for example. This very deep backward compatibility is one of those unsung underappreciated beauties of Perl 5. In my opinion, it is a very cool thing indeed. Challenge 1 (Similar Words) We are given an array of strings with every string consisting of alphabetical characters only. We are asked to count how many pairs of elements of the array are built up from the same set of alphabetical characters. For example, 'aab' and 'aba' share the same set of alphabetical characters {a,b}, while 'aa

PWC 231

PWC 231 Two easy challenges this week. It is tempting to try them in Perl 5, Raku as well as Julia, but alas, I don't have the time. So here goes Perl 5 only. Challenge 1 (Min Max) We are given a list of distinct integers and asked to return the elements that are neither the maximum nor the minimum. If there are no such elements, then return -1. That happens if the list length is 2 or less, in which case every element is perforce either a maximum or minimum or both. I sort the list and return the elements between the head and the tail. I use PDL. Here is the key subroutine: sub min_max {         my $ints=pdl(@_)->uniqvec;     ($ints->dim(0) > 2) ?         ($ints->qsort->(1:(($ints->dim(0))-2))) :         (-1); } Just in case the input is not a list of distinct integers, I force it to its unique elements using the PDL uniqvec method. I then check if the length is 2 or less, in which case we return -1, else we sort and return the sub-piddle between the head and tail

PWC 230

PWC 230 Two easy challenges this week.  Challenge 1 (Separate digits) We are given an array of positive integers say @int, and asked to return another array in which the elements of @int are split into their individual digits. Thus (1,23,456) should give (1,2,3,4,5,6). One easy way to do this in Perl 5 is to combine the elements of @int into a string using 'join', and then split the string into individual characters using split. Here is the key code snippet:     split //, join '', @_; Challenge 2 (Count words) We are given an array of strings @words say, and a single string called $prefix say. We are asked to count how many of the strings in the array @words start with $prefix. This is easy to do with grep. Here is the key snippet:      scalar grep /^$prefix/, @words;

PWC 229

PWC 229 Challenge 1 (Lexicographic Order) We are given a list of strings. We are asked to count the number of elements that are strings whose constituent characters are not all either in weakly monotonically ascending lexicographic order or weakly monotonically descending lexicographic order (i.e., component strings whose characters are NOT either all in ascending or all in descending dictionary order). I use a sub-subroutine &is_sorted that checks if each string is sorted. If the string has less than 3 elements, then it is automatically sorted. Otherwise, we check the order of the first 2 elements, say either element 1 is (lexical) less than or equal to (le) element 2, or element 1 is greater than or equal to (ge) element 2. We proceed to loop through the remaining elements to verify that they have the same ordering relationship (le or ge) as the first two. In the main part of the subroutine, we call &is_sorted on each string in the array (map), then extract the zeroes (not so

PWC 228

PWC 228 Challenge 1 (Unique Sum) We are given an array of integers, and asked to return the sum of only those elements that are unique, i.e., skipping any elements that are repeated. I use a single pass through the array, adding elements as I go, and also counting their frequency with a hash. If the frequency hits 2, then I subtract the element from the running total, and thereafter ignore any further repetitions. I use the ( a ? b : c ) conditional expression. Here is the subroutine:  sub unique_sum {     my @int = @_;          #-- %int : hash to count frequency of each element of @int,     #-- $retval : return value     my (%int, $retval);          #initialize %int values, $retval, to zero     $retval=0;     map {$int{$_}=0} @int;          #-- loop thru' @int counting frequencies and updating $retval     map {         $int{$_}++;                  ($int{$_} > 1) ?             ( ($int{$_} == 2)  ? ($retval -= $_) : 1 )             : ($retval += $_);       }  @int;     $retval; }