PWC 198

PWC 198

Our good host has given us easy challenges this week, which works for me as I am busy at work. Still, I have done them only in Perl 5 and Raku and skipped Julia this time.

Challenge 2 (Prime Count)

We are asked to find the number of prime integers between 0 and a given positive integer $n. The challenge specifies that we are looking for primes that are strictly less than $n (which I nearly missed, but caught in time).

This is an easy one-liner if one does not try to implement a prime sieve from scratch (I don't). Here it is in Raku:

raku -e '(0..^@*ARGS[0]).grep(*.is-prime).elems.say' $@

We need the ^ in ^@*ARGS[0] to exclude $n (the command-line argument) itself from the count. 

In Perl 5, I use the Math::Prime::Util function "prime_count". 

perl -MMath::Prime::Util=prime_count -wl -e 'print prime_count($ARGV[0]-1)' $@

We subtract one from the command-line argument to exclude it from the count. The "prime_count" routine gives the number of primes up to and including its argument.

Challenge 1 (Max Gap)

We are given a list of integers. We are asked to sort them first, then count the occurrences of the gaps between successive elements. For example, for the input list (1,2,3,4) the gaps are 1 between 3 consecutive pairs of elements ( (1,2), (2,3), (3,4))). We are asked to return the count for the highest gap recorded. If the input list has only one element, we return 0.

This is a classic Perl use of a hash (Of course, there are many other ways to do it too). In Perl 5, I sort the list, then iterate through the sorted list counting gaps with a hash, where the key is the gap, and the value is the count for that gap. Then I sort the hash keys and take the value of the highest one.   Here is the sub-routine:

sub max_gap {
    my (@list) = (sort {$a <=> $b} @_);
    (@list <= 2) && (return 0);
    my %gaps;
    
    map {$gaps{$list[$_+1]-$list[$_]}++}
    (0 .. @list-2);
        
    $gaps{ (sort {$b <=> $a} (keys %gaps))[0] };
}

Here is the direct translation to Raku:

sub max-gap (@list) {
    my (@sorted_list) = @list.sort( {$^a <=> $^b} );
    (@list.elems <= 2) && (return 0);
    my %gaps;
        
    (0 .. @sorted_list-2).map( {%gaps{@sorted_list[$_+1]-@sorted_list[$_]}++} );
    
    
    %gaps{ ( (%gaps.keys).sort( {$^b <=> $^a} ))[0] };
}

Both scripts have a silly error. The test for returning zero should be that the list length should be strictly less than two (or one or less), not less than or equal to two as I have it. I didn't read the spec carefully enough when I was scripting. I'll let the programs stand as, let's say, an inadvertent variation from the spec.

Comments

Popular posts from this blog

PWC 215

PWC 227

PWC 234