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)
            ctr = ctr+1
    end
end

Perl 5 key snippet:
 
for my $i (combinations(\@list,2)) {
    ((sum @$i) % $k == 0) && ($ctr++)
}

In Julia, I use the Combinatorics library to get the equivalent of Raku's combination operator. In Perl 5, I use Algorithm::Combinatorics.
 
 

Challenge 2 (Total zero)

We are given two positive integers x and y say. Without loss of generality, let x >= y. We are asked to reduce the integers to zero via a series of operations as follows:

  • If both integers are equal, replace them both with zero. Stop.
  •  Otherwise, replace x with x-y, i.e., x=x-y. 
    • If x is still greater than y, repeat.
    • If x is now less than y, swap x and y, (i.e., (x,y)=(y,x) in Perl) and repeat.
We are asked to count the number of steps it takes until both integers are zero.
 
(This is not quite how the problem is stated by our host, but can be inferred from the examples.)

One can do a bit better than brute force here.

First, notice that we would keep replacing x with x-y until y > x. The number of steps to reach y > x would be the integer part of x / y say n. We can start by adding n to our count, then repeat the same calculation with the pair (y, x - n*y), and so on.

One can notice a few edge cases.

  • If x is divisible by y, then n is the answer, as x-n*y reaches 0. We do not need to go further.
  • From the above, if y=1, then the answer is x. 
  • As noted above, if x=y, then the answer is 1 (we finish in 1 step).

In Raku, I use multi subroutines to set up a recursive solution. I set up versions of the total-zero subroutine for each of the edge cases above. Then I use a recursive call in the default version of the subroutine.

my $times=Int($bigger/$smaller);
return $times + total-zero($smaller, $bigger-$times*$smaller);

In Perl 5 and Julia, I use the same recursive approach as in Raku without the multiple dispatch.

Comments

Popular posts from this blog

PWC 258

PWC 253

PWC 249