Perl Weekly Challenge: Week 205
Challenge 1:
Third Highest
You are given an array of integers.
Write a script to find out the
Third Highest
if found otherwise return the maximum.
Example 1
Input: @array = (5,3,4)
Output: 3
First highest is 5. Second highest is 4. Third highest is 3.
Example 2
Input: @array = (5,6)
Output: 6
First highest is 6. Second highest is 5. Third highest is missing, so maximum is returned.
Example 3
Input: @array = (5,4,4,3)
Output: 3
First highest is 5. Second highest is 4. Third highest is 3.
This probably could have been a one-liner but I didn't make the effort so it is a hideously bloated two lines instead.
First the command line arguments are sorted in descending numeric order and unique values are extracted
(this step is necessary to get the correct answer for e.g. example 3.) into @array
.
my @array = @args.sort({ $^b <=> $^a }).unique;
If the array has three or more values, we take the third highest which is at subscript [2]. Otherwise
we take the maximum value which is at subscript [0]
.
say @array.elems > 2 ?? @array[2] !! @array[0];
For Perl, we have to provide our own unique()
function. I used one from previous challenges. The
rest of the code works that same as in Raku.
my @array = sort { $b <=> $a } unique(\@ARGV);
say scalar @array > 2 ? $array[2] : $array[0];
Challenge 2:
Maximum XOR
You are given an array of integers.
Write a script to find the highest value obtained by XORing any two distinct members of the array.
Example 1
Input: @array = (1,2,3,4,5,6,7)
Output: 7
The maximum result of 1 xor 6 = 7.
Example 2
Input: @array = (2,4,1,3)
Output: 7
The maximum result of 4 xor 3 = 7.
Example 3
Input: @array = (10,5,7,12,8)
Output: 15
The maximum result of 10 xor 5 = 15.
Now this one can definetly be a one-liner.
@*ARGS.combinations(2).map({ @$_[0] +^ @$_[1] }).sort({ $^b <=> $^a }).first.say;
What I did was get all the combinations of 2 command-line arguments with .combinations()
,
XOR each pair and .map()
those back into an array, sort that array in descending numerical order
with .sort()
, take the first value which will be the highest with .first()
and print it with .say()
.
Unfortunately, Perl doesn't have .combinations()
builtin so we have to provide our own code. This has
come up a lot of times in past challenges so I had code handy to cut and paste. With this addition, the
rest of the code does fit into one line.
say 0+(sort { $b <=> $a } map { $_->[0] ^ $_->[1] } combinations(\@ARGV, 2))[0];
Because we don't have .first()
, we wrap the array returned by our manipulations in parentheses and use
the [0]
subscript to get the highest value. An unfortunate side effect is that a warning is triggered
about say
being used as a function so we have to add 0+
in front to prevent it.
The last thing to note is that my combinations()
function returns an array of array references thus the
syntax used in the call to map()
.