Perl Weekly Challenge: Week 198
Challenge 1:
Max Gap
You are given a list of integers,
@list
.Write a script to find the total pairs in the sorted list where 2 consecutive elements has the max gap. If the list contains less then 2 elements then return 0.
Example 1
Input: @list = (2,5,8,1)
Output: 2
Since the sorted list (1,2,5,8) has 2 such pairs (2,5) and (5,8)
Example 2
Input: @list = (3)
Output: 0
The first thing to do is to get @list
from the command line arguments and sort it so
the elements are in ascending numeric order.
my @list = @args.sort({$^a <=> $^b});
The last stipulation in the spec is easy to implement. If @list
has less than two elements, we
print 0 and are done.
if @list.elems < 2 {
say 0;
} else {
If there are two or more, we have more work to do. We need to know what is the maximum gap between
pairs of consecutive elements in @list
and how many pairs have that length. I chose to express this
as a hash called %gaps
where the keys are gap lengths and the values are lists of pairs having that gap length.
my %gaps;
We go through @list
starting from the second element and comparing it to the one before until we reach the end.
Because @list
is sorted numerically, we will never have a negative gap length. As each pair is compared, it is
added to the appropriate key in %gaps
for its gap length.
for 1 .. @list.end -> $i {
%gaps{(@list[$i] - @list[$i - 1])}.push([@list[$i - 1], @list[$i]]);
}
Once that is complete, we sort gaps in terms of gap length. The first element will be the one with the maximum gap length. We count how many pairs under that key and print the answer.
%gaps.sort({ $^b.value.elems <=> $^a.value.elems }).first.value.elems.say;
}
This is the Perl version.
my @list = sort {$a <=> $b} @ARGV;
if (scalar @list < 2) {
say 0;
} else {
my %gaps;
for my $i (1 .. scalar @list - 1) {
push @{$gaps{($list[$i] - $list[$i - 1])}}, [$list[$i - 1], $list[$i]];
}
say scalar @{ $gaps{(sort { $gaps{$b} <=> $gaps{$a} } keys %gaps)[0]} };
}
Challenge 2:
Prime Count
You are given an integer
$n > 0
.Write a script to print the count of primes less than
$n
.
Example 1
Input: $n = 10
Output: 4 as in there are 4 primes less than 10 are 2, 3, 5 ,7.
Example 2
Input: $n = 15
Output: 6
Example 3
Input: $n = 1
Output: 0
Example 4
Input: $n = 25
Output: 9
This can be solved in Raku as a one-liner. First we fetch the first command line argument
and store it in $n
. Then we make a range from 0 to $n
and .grep()
primes from it with .is-prime()
.
We count how many primes we found with .elems()
and print the answer with .say()
.
my $n = @*ARGS[0]; (0 .. $n).grep({ .is-prime }).elems.say
The Perl version is not quite so short because we have to provide our own isPrime()
function. Luckily I have
already written one which I have used in many previous challenges. Now the heart of the script can also be expressed
as one line:
say scalar grep { isPrime($_) } 0 .. $n;