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];

(Full code on Github.)

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];

(Full code on Github.)

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;

(Full code on Github.)

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];

(Full code on Github.)

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().