Perl Weekly Challenge: Week 172
Challenge 1:
Prime Partition
You are given two positive integers,
$m and $n
.Write a script to find out the
Prime Partition
of the given number. No duplicates allowed.For example,
Input: $m = 18, $n = 2
Output: 5, 13 or 7, 11
Input: $m = 19, $n = 3
Output: 3, 5, 11
Another relatively easy week.
my @primes = (1 .. $m).grep({ .is-prime });
my $count = 0;
I started the Raku version of my solution for task 1 with a list of all the prime numbers
less than $m
. I also set up a variable to hold the number of prime partitions found for reasons I shall
explain in a bit.
for @primes.combinations($n) -> @combo {
Now we have a list of primes, .combinations()
gives us a list of all the combinations of those primes with
a length equal to $n
.
if ([+] @combo) == $m {
@combo.join(q{, }).say;
$count++;
}
If the sum (found with [+]
) of the elements of a combination equal $m
, it is a prime partition. We print
it out and increase $count
by 1.
}
unless $count {
say "No such prime partition.";
}
The spec didn't say what to do if $m
doesn't have any prime partitions of length $n
which is a distinct possibility so I
added this last bit. If after examining all combinations, the value of $count
is still 0, we print an error message.
Below is the Perl version. Once I had provided the combinations()
, isPrime()
, and sum()
functions which I had written for
previous challenges, the script worked the same as the Raku version.
my @primes = grep { isPrime($_) } 1 .. $m;
my $count = 0;
for my $combo (combinations(\@primes, $n)) {
if (sum($combo) == $m) {
say join q{, }, @{$combo};
$count++;
}
}
unless ($count) {
say "No such prime partition.";
}
Challenge 2:
Five-number Summary
You are given an array of integers.
Write a script to compute the
five-number summary
of the given set of integers.You can find the definition and example in the wikipedia page.
my @nums = @args.sort;
my $e = @nums.elems;
The referenced Wikipedia page suggest sorting the array of integers into ascending order before starting but because arguments in Raku are immutable, I copied the sorted list into a new list called @nums
. I also stored the length of the list as we will be using that value a lot.
say "minimum: ", @nums.min;
The minimum value of a list is easy to find with the .min()
method.
say "lower quartile: ", $e %% 2 ?? (@nums[$e / 4 - 1] + @nums[$e / 4]) / 2 !! @nums[$e / 4];
say "median: ", $e %% 2 ?? (@nums[$e / 2 - 1] + @nums[$e / 2]) / 2 !! @nums[$e / 2];
say "upper quartile: ", $e %% 2 ?? (@nums[$e / 4 * 3 - 1] + @nums[$e / 4 * 3]) / 2 !! @nums[$e / 4 * 3];
For the next three values, we only need to find the elements at 25%, 50% and 75% of the @nums
list. Hover if the list has an even number will fall between two elements so we find those, add them together and divide by 2 to get the correct answer.
say "maximum: ", @nums.max;
To find the maximum value of a list you merely have to use the .max()
method.
Barring syntactic differences, the Perl version is almost exactly the same.
my @nums = sort { $a <=> $b } @ARGV;
my $e = scalar @nums;
say "minimum: ", $nums[0];
One exception is that Perl has no .min()
method. However because @nums
is sorted in ascending order, the first element (i.e. $nums[0]
) will always be the minimum value.
say "lower quartile: ", $e % 2 == 0 ? ($nums[$e / 4 - 1] + $nums[$e / 4]) / 2 : $nums[$e / 4];
say "median: ", $e % 2 == 0 ? ($nums[$e / 2 - 1] + $nums[$e / 2]) / 2 : $nums[$e / 2];
say "upper quartile: ", $e % 2 == 0 ? ($nums[$e / 4 * 3 - 1] + $nums[$e / 4 * 3]) / 2 : $nums[$e / 4 * 3];
say "maximum: ", $nums[-1];
Similiarly Perl has no .max()
method but we know the last element (i.e. $nums[-1]
) will always be the maximum value.