Posts

Showing posts from October, 2022

PWC 188

PWC 188 Challenge 1 (Divisible pairs) We are given a list of integers, @list say, as well as a scalar integer $k. We are asked to count the number of pairs of elements of @list whose sum is divisible by $k. Thus, if $a and $b are elements of @list, we count ($a,$b) as an eligible pair if ($a+$b) is divisible by $k. This is a potential one-liner in Raku. But I settled for a one-line subroutine. Here is the key snippet: ( 0 .. @test-1) . combinations( 2 ) . grep ({@test[ $_ ] . sum %% $k}) . elems The task specification asks us to find pairs of indices of @list rather than pairs of elements of @list directly. I have followed this specification literally with Raku.  Of course it makes no difference if we get the pairs from the list directly. I did this with my Perl 5 and Julia versions, both of which are derived from the Raku one. Julia key snippet:   for i in collect ( combinations (list, 2 ))        if ( sum (i) % k == 0 )     

PWC 187

PWC 187 Challenge 1 (Days Together) Two friends Foo and Bar vacation in the same city, with the start-dates and end-dates for each one's vacation given in the form 'dd-mm'. The year is assumed to be the same non-leap year for all dates. The task is to work out the number of days when Foo and Bar are both in the city at the same time.  This resolves to finding the number of days between the later start-date and the earlier end-date, including both days in the count (e.g., if they are both the same day, then the count is 1, not zero). This is easy to do with the numerous Date modules in Perl 5, or the built-in Date support in Raku and Julia.  In Perl 5, I used the lightweight fast Date::Calc module exporting the Delta_Days subroutine. Delta_Days counts days between two (year, month, day) triplets, input as a flat list. Since it excludes the second (ending) date from the count, I add 1 to include it for the present task. My Perl 5 script uses simple helper subroutines to parse

PWC 186

PWC 186 Challenge 1 (Zip List) Challenge 1 requires "zipping" two lists  a and b say, by creating a combined list in which the elements are: (a[0] b[0] a[1] b[1] a[2] b[2] ...). The lists are of equal length. There are ready-made functions to do this in all three languages I submit. In Perl 5, List::MoreUtils has a zip function that does exactly this. Raku has the Z operator, so it is as simple as @a Z @b . Julia has a zip function named zip, though the output is not quite what is requested. It returns an array of tuples: [(a[0] b[0]), (a[1] b[1]), ...].  I wrote my own function for the task, using straightforward logic. I just push the elements of the two arrays into a new array in the prescribed order. The key snippet: Perl 5: push @c , ( $$ra_a [ $_ ], $$ra_b [ $_ ]) for (0 .. @$ra_a -1);   Raku: @c . append (@a[ $_ ], @b[ $_ ]) for ( 0 .. @a-1); Julia: for i in 1:length(b)     append!(c, a[i], b[i]) end   Here is my Perl 5 script. Here is my Raku script. Here is m

PWC 185

PWC 185 Challenge 2 (Mask Code) Given a list of arbitrary strings consisting of alphanumeric and other characters, we are asked to run a script that replaces the first four alphanumeric characters in each string with x. Thus (from the test example), 'ab-cde-123' gets converted to 'xx-xxe-123'. This is a one-liner in Perl 5 and Raku. In Perl 5 : perl -E ' for my $test (@ARGV) {$test =~ s/[a-wyz0-9]/x/ for (1 .. 4); say $test} ' ' ab-cde-123 ' ' 123.abc.420 ' ' 3abc-0010.xy ' I loop through the strings in ARGV and for each string loop four times through a substitution regex that finds the next alphanumeric that is not x and replaces it with x.  The same logic in Raku : raku -e ' @*ARGS.map({my $temp=$_; ($temp ~~ s/<[a .. w y z 0 .. 9]>/x/) for (0 .. 3); say $temp;}) ' ' ab-cde-123 ' ' 123.abc.420 ' ' 3abc-0010.xy ' In Julia I do not use a