Posts

PWC 193

PWC 193 Challenge 1 (Binary string) We are given an integer n say, and asked to print out all the binary numbers of length n or less. This is a one-liner in all three languages. In my scripts, n is read from the command line. Here it is for n=3. In Perl 5: perl -e 'for (eval ("0b".(0 x $ARGV[0]). ".." . "0b". (1 x $ARGV[0]))){printf("%b\n",$_)}' 3 In Raku: raku -e 'use MONKEY-SEE-NO-EVAL; for (EVAL("0b" ~ (0 x @*ARGS[0]) ~ ".." ~ "0b" ~ (1 x @*ARGS[0]))) {printf("%b\n",Int($_))}' 3 In Julia: julia -e 'for i in (parse( Int64, "0b" * repeat( "0", parse( Int64,ARGS[1] ))) : parse( Int64, "0b" * repeat( "1", parse(Int64, ARGS[1] )))); println( SubString( bitstring(i), 65-parse(Int64, ARGS[1]))); end;' 3 In all three languages, I iterate through the range 0b0 to 0b111.. (with n 1's), printing in binary format. Julia's version of printf does

PWC 192

PWC 192 Challenge 1 (Binary flip) We are given an integer. We are asked to convert it to its binary representation, and then flip the bits, that is, 1 becomes 0, and 0 becomes 1. From the examples, it is clear that we do not flip leading zeros in the binary representation: i.e., 010 flips to 001, not 101. It is easier to do this in Perl (5 or 6) with string-handling operators rather than bit operators. One first uses sprintf("%b",...) to represent the integer as a string version of its binary form. Then one applies the tr (transliterate) operator on this string to replace [01] with [10]. Then stick a '0b' in front of the resulting string, and call eval on the result to magically make it an integer. Here is my Perl 5 subroutine: sub binary_flip  {     my $b=sprintf("%b",shift);     $b =~ tr/[10]/[01]/;     eval('0b' . $b); } Here is the direct port to Raku: sub binary-flip (Int $n) {     my $b=sprintf("%b",$n);     $b ~~ tr/<[1 0]>/&l

PWC 191

PWC 191 This was a busy week at work again. I managed to do both challenges in Perl 5 and Raku (I skipped Julia this time). But like last week, these are minimal contributions that just satisfy the test examples. Particularly in Challenge 2, my solution is not efficient with a bigger input. I discuss briefly here how my solutions could be improved, but haven't had time to actually attempt the better solutions. Challenge 1 (Twice largest) We are given a list of integers, and asked to find if the biggest integer in the list is weakly more than twice the second-biggest integer.  This is easily done. Sort the list using a numeric sort, and then, if sorted in descending order as I did it, compare the first element in the sorted list with the second. Here is my Perl 5 subroutine to do this: sub twice_largest { my (@list)=@_; my @sorted_list = sort {$b <=> $a} @list; (($sorted_list[0]) >= (2*$sorted_list[1])) ? 1 : (-1); } And here is the Raku version: sub twice-larg

PWC 190

PWC 190 This week was busy at work. I thought I would only be able to do Challenge 1, but I managed to eke out a minimal solution in Perl 5 and Raku to Challenge 2 too (I passed on Julia for Challenge 2 this time). Challenge 1 (Capital Detection) We are given a string consisting of alphabets only (/^[A-Za-Z]+$/), and asked to test if one of the following conditions is met: The initial letter is uppercase, and all the rest are lowercase (as in "Perl"). All the letters are uppercase (as in "COBOL"). All the letters are lowercase (as in "bash"). This is one of those Perl programming exercises where the python philosophy almost applies: there's one very good way to do it, and that's the way to go. That is via a regex. This would be an easy one-liner, but I have used a subroutine instead. Here is the key snippet in Perl 5. ($s =~ /^[A-Z]?[a-z]+$|^[A-Z]+$|^[a-z]+$/) ? 1 : 0; Here is the same thing in Raku (a direct translatio

PWC 189

PWC 189 Challenge 1 (Greater Character) "You are given an array of characters (a..z) and a target character. Write a script to find out the smallest character in the given array lexicographically greater than the target character." I sort the list. Then, in Perl 5 and Julia, I loop through the sorted elements until I hit one just bigger than the target. In Raku, I just use grep. Here is the key snippet from my Raku script: @arry . sort ({$ ^ a cmp $ ^ b}) . grep ({ $_ gt $target}) . min ; Here is my Perl 5 script Here is my Raku script Here is my Julia script Challenge 2 (Array Degree) "You are given an array of 2 or more non-negative integers. Write a script to find out the smallest slice, i.e. contiguous subarray of the original array, having the degree of the given array." The degree of the array is the maximum frequency with which any element occurs. Thus for the example given (1,3,3,2), the degree is 2 (the frequency of the most common or modal element 3).

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